正则表达式匹配包含指定字符串的多行条目

Regex match multiline entries containing specified string

我正在尝试使用正则表达式(PCRE 引擎)收集描述 Rectangle 3 的语句。这是专有 TGML-ish 语言的抓取项目的一部分。我

输入如下所示:

<Rectangle is 
    good>99</Rectangle>
<Rectangle is 
    bad>99</Rectangle>
<Rectangle is 
    ugly>3</Rectangle>
<Rectangle is 
    fat>99</Rectangle>
<Rectangle is 
    janky6789>99</Rectangle>
<Rectangle is 
    34+35>99</Rectangle>
<Rectangle is 
    <>>98</Rectangle>
<Rectangle is 
    chicken>3</Rectangle>
<Rectangle 1 is 
    holy>97</Rectangle>

输出如下所示:

<Rectangle is 
    ugly>3</Rectangle>
<Rectangle is 
    chicken>3</Rectangle>

我可以获得包含 Rectangle 3 的匹配项,但它们也包含它之前的所有内容。

<Rectangle\X*?3$\X*?<\/Rectangle>

似乎应该对此有某种分组、回溯或递归技巧,但我想不出来。

您可以使用带否定字符 类 的正则表达式,而不是懒惰地将任何字素与 \X*?:

匹配
<Rectangle[^>]*>3$[^<]*<\/Rectangle>

参见regex demo

请注意,您的 \X*? 匹配任何字素,包括 <>、换行符等,因此它将尽可能匹配以使后续模式匹配。因此,使用 [^>]*[^<]* 您将能够限制模式可以在固定子模式之间匹配的字符。

详情

  • <Rectangle - 文字字符串
  • [^>]* - >
  • 以外的任何零个或多个字符
  • >3$ - >3$ 字符串
  • [^<]* - <
  • 以外的任何零个或多个字符
  • <\/Rectangle> - </Rectangle> 字符串。

只需匹配空格、非空格,然后是您的目标 >3$,以 .* 结尾以捕获该行的其余部分:

<Rectangle is\s+\S+>3$.*

参见live demo