正则表达式捕获其间重复组数量未知的文本
Regex to capture text with unknown number of repeated groups in between
我正在尝试在第二层下解析以下文本中 "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)
- 出现 "Catastrophic backtracking" 错误 直到 您删除包含
Laundry: 1
的最后一行。是因为匹配太多还是什么原因?
- 删除该行后,正则表达式仅捕获
OTHER LEVEL
下的 last 匹配。返回“2”而不是 [=12= 下的匹配].
有时 Dining:
在 SECOND LEVEL
下不存在,因此不应返回任何内容。
什么是只捕获 SECOND LEVEL
的 Dining:
号码的正则表达式,如果它不存在则 returns 什么都没有?首选直接正则表达式,如果可能,不要在 Java 中循环。谢谢
使用基于负前瞻的正则表达式。
"(?m)^\s*\bSECOND LEVEL\n(?:(?!\n\n)[\s\S])*\bDining:\s*(\d+)"
我所知道的关于灾难性回溯 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$]*)
我正在尝试在第二层下解析以下文本中 "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)
- 出现 "Catastrophic backtracking" 错误 直到 您删除包含
Laundry: 1
的最后一行。是因为匹配太多还是什么原因? - 删除该行后,正则表达式仅捕获
OTHER LEVEL
下的 last 匹配。返回“2”而不是 [=12= 下的匹配].
有时 Dining:
在 SECOND LEVEL
下不存在,因此不应返回任何内容。
什么是只捕获 SECOND LEVEL
的 Dining:
号码的正则表达式,如果它不存在则 returns 什么都没有?首选直接正则表达式,如果可能,不要在 Java 中循环。谢谢
使用基于负前瞻的正则表达式。
"(?m)^\s*\bSECOND LEVEL\n(?:(?!\n\n)[\s\S])*\bDining:\s*(\d+)"
我所知道的关于灾难性回溯 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$]*)