如何匹配满足我的正则表达式模式的最短字符序列?

AgA*_*AgA 3 regex perl matching

我有一串 "ajjjjjjjjjaab"

我想要一个匹配最后一个"ab"而不是整个字符串甚至偶数的模式"aab"

/a.*?b/  # returns two groups
Run Code Online (Sandbox Code Playgroud)

要么

/a.??b/ # matches last aab
Run Code Online (Sandbox Code Playgroud)

都不行。

Kob*_*obi 5

解决问题的一种简单方法是匹配:

.*(a.*b)
Run Code Online (Sandbox Code Playgroud)

首先.*贪婪,它尽可能地匹配。然后,您将获得一个具有您真正需要的匹配项的捕获组($1)。请注意,这假设您正在匹配模式的最后一次出现。您可能想要在字符串末尾附近.*(a.*?b)有多个bs,并且想要在last之后的第一个a

  • @user-不是我所知道的。.Net可以从右到左匹配,或者您总是可以反转字符串并匹配`b。*?a`。您也可以尝试类似`a((?!a)。)* b`​​(或`a [^ a] * b`)的方法,但是使用复杂的模式可能会变得混乱-我*假设*您需要一点超过`a`和`b` ... (2认同)

ike*_*ami 5

之一:

/a[^a]*b/
/a[^ab]*b/
Run Code Online (Sandbox Code Playgroud)

如果ab实际上是更复杂的模式,则可以使用以下方法:

/a(?:(?!a).)*b/s
/a(?:(?!a|b).)*b/s
Run Code Online (Sandbox Code Playgroud)

如果ab表示长/复杂模式,则可以避免像其他任何代码一样使用变量来重复它们。

my $re1 = qr/a/;
my $re2 = qr/b/;

/$re1(?:(?!$re1|$re2).)*$re2/s
Run Code Online (Sandbox Code Playgroud)

一个人也可以使用子模式。

/
   (?&A) (?:(?!(?&A)|(?&B)).)* (?&B)

   (?(DEFINE)
      (?<A> a )
      (?<B> b )
   )
/xs
Run Code Online (Sandbox Code Playgroud)