匹配文本后跟可选模式

时间:2014-08-28 23:09:08

标签: regex perl

我正在尝试编写一个匹配字符串后跟可选模式的正则表达式。

以下是我想要匹配match/string

的三个输入字符串的示例
/any/path/match/string
/any/path/match/string/pattern
/any/path/match/string/pattern/something/else

其中/any/path/pattern是静态文本,match/string可以是任何文本。

我试过这个

print $1 if m,/any/path/(.+)(?=/pattern/)?,

但它匹配整个输入字符串,因为.+是贪婪的。

2 个答案:

答案 0 :(得分:1)

正如你已经猜测的那样,你的问题是贪婪匹配。

请记住,如果你在使用正则表达式时遇到问题,你可以随时将逻辑分解为步骤:

print +(split m{/pattern\b}, $1)[0] if m{^/any/path/(.+)};

要使用单个正则表达式执行此操作,有两种方法:

  1. 通过在其前面添加否定前瞻断言来限制任何字符.可以匹配的内容。
  2. 使用非贪婪匹配结束边界线。
  3. 以下演示了这两种方法:

    use strict;
    use warnings;
    
    while (<DATA>) {
        print "\nString = $_";
    
        if (m{^/any/path/( (?:(?!/pattern\b).)* )}x) {
            print "  Neg Lookahead        - $1\n"
        }
    
        if (m{^/any/path/(.*?)(?:/pattern\b|$)}x) {
            print "  Nongreedy with bound - $1\n"
        }
    }
    __DATA__
    /any/path/match/string
    /any/path/match/string/pattern
    /any/path/match/string/pattern/something/else
    

    输出:

    String = /any/path/match/string
      Neg Lookahead        - match/string
      Nongreedy with bound - match/string
    
    String = /any/path/match/string/pattern
      Neg Lookahead        - match/string
      Nongreedy with bound - match/string
    
    String = /any/path/match/string/pattern/something/else
      Neg Lookahead        - match/string
      Nongreedy with bound - match/string
    

答案 1 :(得分:0)

您可以使用此正则表达式:

/any/path/(\w+?/\w+)/pattern|/any/path/(\w+?/\w+)$

<强> Working demo

enter image description here