正则表达式:匹配组如果存在,否则忽略并继续其他匹配

时间:2016-06-01 11:11:06

标签: java regex regex-greedy

我一直在尝试匹配以下数据中的正则表达式模式:

字符串:

  

TestData 到1colon分隔符列表有1行。设置...值为:1保存错误: 267467374736437-TestInfo 发送错误

要匹配的词语:

  
      
  1. TESTDATA
  2.   
  3. 267467374736437-TestInfo
  4.   

使用正则表达式:

(.+?\s)?.*(\s\d+-.*?\s)?

这里的场景是第二场比赛(267467374736437-TestInfo)可以在要匹配的字符串中不存在。所以,如果它存在,我希望它是匹配,否则继续其他匹配。由于这个我添加零或一个匹配量词?到上面的组模式。但是它一起忽略了第二组。

如果我使用以下模式:

`(.+?\s)?.*(\s\d+-.*?\s)`

匹配得很好但是如果字符串" 267467374736437-TestInfo "则会失败来自匹配字符串,因为它没有"?"量词。

请帮我理解哪里出错了。

2 个答案:

答案 0 :(得分:0)

我宁愿不使用复杂的正则表达式,这将是丑陋和维护的噩梦。相反,一种简单的方法是分割字符串并抓住第一个术语,然后使用智能正则表达式来确定第二个术语。

String input = "TestData to 1colon delimiter list has 1 rows.Set...value is: 1 Save Error: 267467374736437-TestInfo send Error";
String first = input.split(" ")[0];
String second = input.replaceAll(".*Save Error:\\s(.*)?\\s", "$1");

探索正则表达式:

Regex101

答案 1 :(得分:0)

如果出现更通用的模式,最后的可选模式几乎永远不会匹配。在你的情况下,贪婪的点.*抓住整个行的其余部分直到最后,并且因为最后一个模式是可选的,所以正则表达式引擎称它为一天并且不会尝试为它提供任何文本。

如果你有一个懒惰的点.*?,它唯一可以工作的位置就在前一个子模式之后,这种情况很少见。

因此,你只能依靠一个顽固的贪婪令牌:

^(\S+)(?:(?!\d+-\S).)*(\d+-\S+)?

请参阅regex demo。 或者展开的版本:

^(\S+)\D*(?:\d(?!\d*-\S)\D*)*(\d+-\S+)?