怎么样?在正则表达式中使量词变得懒惰

时间:2013-07-01 08:20:03

标签: regex operators quantifiers

我最近一直在研究正则表达式,并认为?运算符使*+?懒惰。我的问题是它是如何做到的?是*?例如是特殊运算符,还是?*有影响?换句话说,正则表达式是否将*?识别为一个运算符本身,或者正则表达式将*?识别为两个单独的运算符*??如果*?被识别为两个单独的运算符,?如何影响*以使其变得懒惰。如果?表示*是可选的,那么这不应该意味着*根本不存在。如果是这样,那么在语句中.*?不会正则表达式匹配单独的字母和整个字符串而不是较短的字符串?请解释一下,我很想了解。非常感谢。

4 个答案:

答案 0 :(得分:13)

?在不同的情境中可能意味着很多不同的东西。

  • 遵循正常的正则表达式标记(字符,速记,字符类,组......),表示“匹配前一项0-1次”。
  • 按照?*+{n,m}之类的量词,它会采用不同的含义:“制作上一个量词懒惰而不是贪婪(如果这是默认值;但是可以改变 - 例如在PHP中,/U修饰符默认使所有量词变得懒惰,因此额外的?使它们变得贪婪。 / LI>
  • 在左括号后面,它标记了一个特殊构造的开头,例如

    a)(?s):模式修饰符(“打开dotall模式”)
    b)(?:...):使群组不被捕获 c)(?=...)(?!...):前瞻性断言
    d)(?<=...)(?<!...):lookbehind断言
    e)(?>...):原子组
    f)(?<foo>...):命名捕获组
    g)(?#comment):内联注释,由正则表达式引擎忽略 h)(?(?=if)then|else):条件

和其他人。并非所有正则表达式都具有所有结构。

  • 在字符类([?])中,它只是匹配逐字?

答案 1 :(得分:4)

我认为一点历史会让人们更容易理解。当Larry Wall希望增加正则表达式语法以支持新功能时,他的选择受到严重限制。他不能仅仅(例如)判断%现在是支持新功能“XYZ”的元字符。这将打破使用%匹配文字百分号的数百万现有正则表达式。

可以做的是采用已经定义的元字符并以其原始函数没有意义的方式使用它。例如,连续包含两个量词的任何正则表达式都是无效的,所以可以安全地说?之后另一个量词现在把它变成一个不情愿的量词(一个比“懒惰”IMO好得多的名字; < em> non-greedy 也好。因此,您的问题的答案是?修改 **?是一个单一的实体:一个不情愿的量词。占有量词+*+{0,2}+也是如此。

组语法发生了类似的过程。在未转义的左括号之后有一个量词是没有意义的,所以可以说(?现在标志着一个特殊的群体结构的开始。但单独的问号只会支持一个新功能,因此要遵循的?本身必须至少再跟一个字符来表示它是哪种类型组((?:...),{{ 1}}等。同样,(?<!...)是一个单独的实体:非捕获组的开始分隔符。

我不知道他为什么两次都使用问号。我知道Perl 6 Rules(自下而上重写Perl 5正则表达式)已经废除了所有垃圾并使用了一种无限更合理的语法。

答案 2 :(得分:1)

想象一下,您有以下文字:

BAAAAAAAAD

以下正则表达式将返回:

/B(A+)/ => 'BAAAAAAAA'
/B(A+?)/ => 'BA'
/B(A*)/ => 'BAAAAAAAA'
/B(A*?)/ => 'B'

添加“?” +和*运算符使它们“懒惰” - 即它们将匹配表达式所需的绝对最小值为真。默认情况下,*和+运算符是“贪婪的”,并尝试匹配AS MUCH AS POSSIBLE以使表达式为真。

记住+表示“一个或多个”,所以最小值将是“如果可能的话,一个,如果绝对必要则更多”,而最大值将是“如果可能的话,一个,如果绝对必要,则为一个”。

并且*表示“零或更多”,因此最小值将是“如果可能,则更多,如果绝对必要则更多”,而最大值将是“如果可能则全部,如果绝对必要则为零”。

答案 3 :(得分:0)

我猜这很大程度上取决于实施情况。但由于我所知道的每个量词都可以用?进行修改,因此以这种方式实现它可能是合理的。