正则表达式捕获其间重复组数量未知的文本

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)

  1. 出现 "Catastrophic backtracking" 错误 直到 您删除包含 Laundry: 1 的最后一行。是因为匹配太多还是什么原因?
  2. 删除该行后,正则表达式仅捕获 OTHER LEVEL 下的 last 匹配。返回“2”而不是 [=12= 下的匹配].

有时 Dining:SECOND LEVEL 下不存在,因此不应返回任何内容。

什么是只捕获 SECOND LEVELDining: 号码的正则表达式,如果它不存在则 returns 什么都没有?首选直接正则表达式,如果可能,不要在 Java 中循环。谢谢

使用基于负前瞻的正则表达式。

"(?m)^\s*\bSECOND LEVEL\n(?:(?!\n\n)[\s\S])*\bDining:\s*(\d+)"

DEMO

我所知道的关于灾难性回溯 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$]*)