使用超前表达式匹配组

时间:2017-06-26 09:07:16

标签: java regex scala

我在匹配包含超前表达式的组时遇到问题。我不知道为什么这些表达不起作用:

"""((?<=^)(.*)(?=\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)

有谁知道这个问题的解决方案?

2 个答案:

答案 0 :(得分:1)

多个匹配

您可以将模式修复为

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

请参阅regex demo。重点是引入|交替运算符来匹配2个子模式中的任何一个。请注意,您不需要将^字符串锚点的开头放入lookbehind,因为^已经是零宽度断言。此外,有太多的分组,你似乎没有任何方式使用。另外,要匹配文字点,您需要将其转义(. - &gt; \.)。

要获得多个匹配项,您可以使用以下代码段:

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 :(得分:0)

你的比赛并不紧挨着, 试试这个: &#34;&#34;&#34;((小于??。= ^)(*)(= \ S \ d {1,3} \ \ d {1,3} \ \ d { 1,3} \ \ d {1,3} \ S%))*((小于= [\ W:]。?\ S)(\ W +)(= \ S [CR]))&# 34;&#34;&#34; 我刚刚在它们之间添加了。*,它适用于您发送的链接:)