【问题标题】:Using regular expressions how do I find a pattern surrounded by two other patterns without including the surrounding strings?使用正则表达式如何找到被其他两个模式包围的模式而不包括周围的字符串?
【发布时间】:2010-09-16 13:01:38
【问题描述】:

我想使用正则表达式(Perl 兼容)能够找到一个被其他两个模式包围的模式,但不包括匹配周围模式的字符串。

例如,我希望能够找到以下字符串的出现:

Foo Bar Baz

但只有匹配包含中间部分:

酒吧

我知道这是可能的,但我不记得该怎么做。

【问题讨论】:

    标签: regex


    【解决方案1】:

    在一般情况下,您可能不能。最简单的方法是匹配所有内容并使用反向引用来捕获感兴趣的部分:

    Foo\s+(Bar)\s+Baz
    

    这与不包括匹配中的周围文本不同。如果您只想提取“Bar”,这可能无关紧要,但如果您多次匹配同一个字符串并且需要从上一个匹配停止的地方继续,这将很重要。

    在某些情况下,环顾会起作用。 Tomalak 的建议:

    (?<=Foo\s)Bar(?=\sBaz)
    

    仅适用于固定宽度的后视(至少在 Perl 中)。从 Perl 5.10 开始,\K 断言可用于有效地提供可变宽度的后视:

    Foo\s+\KBar(?=\s+Baz)
    

    它应该能够在所有情况下执行您要求的操作,但需要您在 Perl 5.10 中实现它。

    虽然这很方便,但没有与 \K 等效的方法来结束匹配的文本,因此您必须使用前瞻。

    【讨论】:

    • 优秀。如果可以的话,我会给 +2 :)
    • 我也会给它+2,因为引用了 Perl 5.10 中的新功能。
    【解决方案2】:

    使用lookaround:

    (?<=Foo\s)Bar(?=\sBaz)
    

    这将匹配前面为“Foo”并后面为“Baz”的任何“Bar”,并用一个空格分隔。 “Foo”和“Baz”不会出现在决赛中。

    【讨论】:

    • 这行不通...来自 perl 正则表达式手册 perlre: (?
    • 糟糕,我没想到。模式适应。
    • 您的正则表达式返回 Bar 前后的空格。如果 Bar 前后只有一个空格,则 (?
    • 已经完成。太早点击“发布”,你看到的是中间版本。 ;-)
    【解决方案3】:

    $string =~ m/Foo (Bar) Baz/

    $1

    这可能不是您想要的,因为匹配仍然是“Foo Bar Baz”。但它向您展示了如何只获取您感兴趣的部分。否则您可以使用前瞻和后瞻来获得匹配而不消耗字符...

    【讨论】:

      【解决方案4】:

      括号定义分组。

      "Foo (Bar) Baz"
      

      例子

      ~> cat test.pl
      $a = "The Foo Bar Baz was lass";
      
      $a =~ m/Foo (Bar) Baz/;
      
      print $1,"\n";
      ~> perl test.pl
      Bar
      

      【讨论】:

      • 哇,你居然给了一个完整的剧本,我不得不投票给这个。
      猜你喜欢
      • 1970-01-01
      • 2011-05-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-31
      • 2017-06-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多