问题描述
我正在尝试使用正则表达式(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\$.*