2017-06-26 58 views
1

我有匹配包含超前表達式的組的問題。我不知道爲什麼這個表達式不起作用:匹配組與超前表達式

"""((?<=^)(.*)(?=\s\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\s%))((?<=[\w:]\s)(\w+)(?=\s[cr]))""" 

當我單獨編譯它們,例如:

"""(?<=^)(.*)(?=\s\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\s%)""" 

我得到正確的結果

我的示例文本:

May 5 23:00:01 10.14.3.10 %ASA-6-302015: Built inbound UDP connection 

表達式使用此工具進行過檢查:http://regex-testdrive.com/en/dotest

我的Scala代碼:

import scala.util.matching.Regex 
val text = "May 5 23:00:01 10.14.3.10 %ASA-6-302015: Built inbound UDP connection" 
val regex = new Regex("""((?<=^)(.*)(?=\s\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\s%))((?<=[\w:]\s)(\w+)(?=\s[cr]))""") 
val result = regex.findAllIn(text) 

有誰知道這個問題的解決方案?

+0

鏈接你試圖讓。 '5月5日23:00:01'和'UDP'? –

回答

1

多個匹配

您可以修復圖案

^.*?(?=\s\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\s%)|(?<=[\w:]\s)\w+(?=\s[cr]) 

regex demo。重點是引入|替代運算符來匹配2個子模式中的任何一個。請注意,您不需要將^字符串錨的起始位置置於倒序後,因爲^已經是零寬度斷言。此外,有太多的分組,你似乎沒有任何使用。此外,要匹配文字點,您需要將其轉義(. - >\.)。

要獲得多個匹配,你可以使用下面的代碼片段:

val text = "May 5 23:00:01 10.14.3.10 %ASA-6-302015: Built inbound UDP connection" 
val regex = """^.*?(?=\s\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}\s%)|(?<=[\w:]\s)\w+(?=\s[cr])""".r 
val result = regex.findAllIn(text) 
result.foreach { x => println(x) } 
// => May 5 23:00:01 
// UDP 

Scala online demo

請注意,一旦某個模式與.FindAllIn一起使用,它將不會默認錨定,因此您將獲得輸入字符串中的所有匹配項。

您可以使用捕獲組

另一種方法是匹配整條生產線,同時捕捉必要位與捕獲組:

val text = "May 5 23:00:01 10.14.3.10 %ASA-6-302015: Built inbound UDP connection" 
val regex = """^(.*?)\s+\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\s%.*[\w:]\s+(\w+)\s+[cr].*""".r 
val results = text match { 
    case regex(date, protocol) => Array(date, protocol) 
    case _ => Array[String]() 
} 
// Demo printing 
results.foreach { m => 
    println(m) 
} 

another Scala demo。由於match需要全字符串匹配,因此在模式結尾處添加.*,並且只有相關的未轉義的(...)對保留在模式中。請參閱regex demo here

+1

謝謝你非常專業的答案。 – jesky

0

你的比賽不是彼此相鄰, 試試這個:

"""((?<=^)(.*)(?=\s\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\s%)).*((?<=[\w:]\s)(\w+)(?=\s[cr]))""" 

我剛添加的*兩者之間,它的工作原理您發送:)