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

问题描述

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

输入看起来像这样:

<Rectangle is 
    good>99$1</Rectangle>
<Rectangle is 
    bad>99$2</Rectangle>
<Rectangle is 
    ugly>3$3</Rectangle>
<Rectangle is 
    fat>99$4</Rectangle>
<Rectangle is 
    janky6789>99$5</Rectangle>
<Rectangle is 
    34+35>99$6</Rectangle>
<Rectangle is 
    <>>98$7</Rectangle>
<Rectangle is 
    chicken>3$8</Rectangle>
<Rectangle 1 is 
    holy>97$9</Rectangle>

输出如下所示:

<Rectangle is 
    ugly>3$3</Rectangle>
<Rectangle is 
    chicken>3$8</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