首页 文章

正则表达式前瞻,后观和原子团体

提问于
浏览
316

我在我的正则表达式体内发现了这些东西,但我还不清楚我能用它们做什么 . 有人有例子,所以我可以尝试了解它们是如何工作的吗?

(?!) - negative lookahead
(?=) - positive lookahead
(?<=) - positive lookbehind
(?<!) - negative lookbehind

(?>) - atomic group

3 回答

  • 588

    例子

    给定字符串 foobarbarfoo

    bar(?=bar)     finds the 1st bar ("bar" which has "bar" after it)
    bar(?!bar)     finds the 2nd bar ("bar" which does not have "bar" after it)
    (?<=foo)bar    finds the 1st bar ("bar" which has "foo" before it)
    (?<!foo)bar    finds the 2nd bar ("bar" which does not have "foo" before it)
    

    你也可以把它们结合起来:

    (?<=foo)bar(?=bar)    finds the 1st bar ("bar" with "foo" before it and "bar" after it)
    

    定义

    向前看正面(?=)

    查找表达式A,其中表达式B如下:

    A(?=B)
    

    向前看负面(?!)

    找到表达式B不遵循的表达式A:

    A(?!B)
    

    看看正面(?<=)

    查找表达式B前面的表达式A:

    (?<=B)A
    

    看看负面(?<!)

    查找表达式B不在其中的表达式A:

    (?<!B)A
    

    原子团(?>)

    原子组退出组并在组内第一个匹配的模式后抛弃替代模式(禁用回溯) .

    应用于 foots

    • (?>foo|foot)s 将匹配其第一个替代 foo ,然后失败,因为 s 没有立即跟随,并且因为回溯被禁用而停止

    非原子组将允许回溯;如果后续匹配失败,它将回溯并使用替代模式,直到找到整个表达式的匹配或所有可能性都用完为止 .

    • (foo|foot)s 适用于 foots 将:

    • 匹配其第一个替代 foo ,然后失败,因为 s 没有立即跟随 foots ,并回溯到其第二个替代方案;

    • 匹配其第二个替代 foot ,然后成功 s 紧跟在 foots ,并停止 .

    一些资源

  • 197

    Lookarounds是零宽度断言 . 他们检查正则表达式(朝向当前位置的右侧或左侧 - 基于前方或后方),在找到匹配时成功或失败(基于它是正还是负)并丢弃匹配的部分 . 它们不消耗任何字符 - 跟随它们的正则表达式的匹配(如果有的话)将从相同的光标位置开始 .

    阅读regular-expression.info了解更多详情 .

    • 积极前瞻:

    句法:

    (?=REGEX_1)REGEX_2
    

    仅在REGEX_1匹配时匹配;在匹配REGEX_1之后,匹配被丢弃并且搜索REGEX_2从相同位置开始 .

    例:

    (?=[a-z0-9]{4}$)[a-z]{1,2}[0-9]{2,3}
    

    REGEX_1是 [a-z0-9]{4}$ ,它匹配四个字母数字字符,后跟行尾 .
    REGEX_2是 [a-z]{1,2}[0-9]{2,3} ,它匹配一个或两个字母,后跟两个或三个数字 .

    REGEX_1确保字符串的长度确实为4,但不消耗任何字符,以便搜索REGEX_2在同一位置开始 . 现在REGEX_2确保该字符串与其他一些规则匹配 . 如果没有前瞻,它将匹配长度为3或5的字符串 .

    • 否定前瞻

    句法:

    (?!REGEX_1)REGEX_2
    

    仅在REGEX_1不匹配时匹配;检查REGEX_1后,搜索REGEX_2的位置相同 .

    例:

    (?!.*\bFWORD\b)\w{10,30}$
    

    预见部分检查字符串中的 FWORD ,如果找到则失败 . 如果找不到 FWORD ,则前瞻成功,以下部分验证字符串的长度是否在10到30之间,并且它只包含单词字符 a-zA-Z0-9_

    后视类似于前瞻:它只是在当前光标位置后面 . 像javascript这样的一些正则表达式风格不支持后置断言 . 大多数支持它的风格(PHP,Python等)要求后视部分具有固定长度 .

    • 一旦令牌匹配,原子组基本上会丢弃/忘记组中的后续令牌 . 查看此页面以获取atomic groups的示例
  • 0

    Grokking迅速看起来 .
    如何区分前瞻和后瞻?和我一起游2分钟:

    (?=) - positive lookahead
    (?<=) - positive lookbehind
    

    假设

    A  B  C #in a line
    

    现在,我们问B,你在哪里?
    B有两个解决方案来声明它的位置:

    一,B领先A并且有C bebind
    二,B是C的前方(前瞻)和后方(后视)A .

    正如我们所看到的,两种解决方案中的背后是相反的 .
    正则表达式是解决方案二 .

相关问题