正则表达式可选组解析

时间:2017-08-22 18:42:02

标签: regex

几个小时一直在摆弄......

我试图解析此表单的错误消息:

1
 2
  8
 3
  5
   7
  6
 4

我可以使用以下正则表达式做到这一点:

[error]  C:\Me\MyPath\myFile.scala:18:22: not found: value getaa

正确生成群组:

\[(error|warn)\]\s+(.+):(\d+):(?:\d+:)\s+(.+)$

但为了使其更加健壮,我需要使error C:\Me\MyPath\myFile.scala 18 not found: value getaa 部分可选(因为某些版本的scala编译器不输出列号)。换句话说,它也需要为此字符串生成与上面相同的组:

22:

我尝试在可选组后添加问号,但这不起作用 - 它会弄乱原始组。我假设有一些关于懒惰与贪婪的东西,我不理解。 {regex101上的Here is a working sample。谢谢你的帮助。

2 个答案:

答案 0 :(得分:3)

您需要添加两个问号:

\[(error|warn)\]\s+(.+?):(\d+):(?:\d+:)?\s+(.+)$
                      ^                ^

查看regex demo

.+?将尽可能少地匹配换行符以外的任何1个字符,因此将匹配第一次出现的子模式。第二个?会使(?:\d+:)组可选。

完整模式详情

  • \[ - [
  • (error|warn) - 两个子字符串中的一个(errorwarn
  • \] - 或仅] - 一个]字符
  • \s+ - 1+空格
  • (.+?) - 除了换行符之外的任何1个字符,尽可能少,直到第一个......
  • : - 冒号
  • (\d+) - 第2组:一个或多个数字
  • : - 冒号
  • (?:\d+:)? - 一个非1个数字的非捕获组和1或0次后的冒号
  • \s+ - 1+空格
  • (.+) - 第3组:该行的其余部分
  • $ - 字符串结尾(请注意,这里没有必要,因为.+是一个贪婪的子模式)

答案 1 :(得分:3)

你猜错了。这是由于.+的贪婪。它会占用整个输入文本,然后尝试通过一次放弃一个字符来回溯,直到模式结束匹配。

根据经验,除非明确想要转到输入的末尾,否则永远不会.+

这是固定模式:

^\[(error|warn)\]\s+(.+?):(\d+):(?:(\d+):)?\s+(.+)$

Demo