我正在尝试解析在下面的文章“SECOND LEVEL”下面的“Dining:”后面的数字。所以应该返回'666'。
MAIN LEVEL
Entrance: 11
Dining: 33
SECOND LEVEL
Entrance: 4444
Living: 5555
Dining: 666
THIRD LEVEL
Dining: 999
Kitchen: 000
Family: 33332
如果我使用类似(?:\bDining:\s)(.*\b)
的内容,则会捕获MAIN下的第一个匹配项。我正在尝试在正则表达式中指定SECOND LEVEL
,然后是重复模式:新行,多个空格,然后是任何文本,直到找到Dining:
。 This demo说明了我遇到的两个问题。使用的正则表达式是:(?:\bSECOND\sLEVEL(\n\s+.*)*Dining:)(.*\b)
Laundry: 1
的最后一行。这是由太多比赛引起的吗? OTHER LEVEL
下的最后匹配..返回'2'而不是SECOND LEVEL
下的匹配。 有时Dining:
下不存在SECOND LEVEL
,因此不应返回任何内容。
什么是只捕获SECOND LEVEL
的{{1}}号码的正则表达式,如果它不存在则返回什么?直接正则表达式首选,如果可能的话,在Java中没有循环。感谢
答案 0 :(得分:2)
答案 1 :(得分:1)
我所知道的灾难性回溯from here的最佳示例是(x+x+)+y
。也就是说,它无法找出包含x的捕获组的正确边界,因为有太多方法可以将它们分开。
xxxxy是前两个+一次,第三个两次,或者前两次和第三次一次,或者第一次三次,另一次一次和最后一次。正如你所看到的那样危险!
您(?:\bSECOND\sLEVEL(\n\s+.*)*Dining:)(.*\b)
注意(\n\s+.*)*
.*
与之前的\n\s
结合使用后,可能会成为一场噩梦,并附带*
。它应该被重写(\n\s+[^\s\n][^\n]*)*
这可以确保每个量词在下一次开始之前结束,从而最大限度地减少回溯。
考虑到这种想法,我提出了以下正则表达式来匹配你的字符串:
(?<=SECOND LEVEL\n)(?:\s+(?:[^\s\n:][^\n:]*):[^\n]*)*\s+Dining:\s*([^\s\n][^\n$]*)