zoukankan      html  css  js  c++  java
  • 先行断言和后行断言

    后行断言

    JavaScript 语言的正则表达式,只支持先行断言(lookahead)和先行否定断言(negative lookahead),不支持后行断言(lookbehind)和后行否定断言(negative lookbehind)。目前,有一个提案,引入后行断言,V8 引擎 4.9 版已经支持。

    ”先行断言“指的是,x只有在y前面才匹配,必须写成/x(?=y)/。比如,只匹配百分号之前的数字,要写成/d+(?=%)/。”先行否定断言“指的是,x只有不在y前面才匹配,必须写成/x(?!y)/。比如,只匹配不在百分号之前的数字,要写成/d+(?!%)/

    /d+(?=%)/.exec('100% of US presidents have been male')  // ["100"]
    /d+(?!%)/.exec('that’s all 44 of them')                 // ["44"]
    

    上面两个字符串,如果互换正则表达式,就不会得到相同结果。另外,还可以看到,”先行断言“括号之中的部分((?=%)),是不计入返回结果的。

    “后行断言”正好与“先行断言”相反,x只有在y后面才匹配,必须写成/(?<=y)x/。比如,只匹配美元符号之后的数字,要写成/(?<=$)d+/。”后行否定断言“则与”先行否定断言“相反,x只有不在y后面才匹配,必须写成/(?<!y)x/。比如,只匹配不在美元符号后面的数字,要写成/(?<!$)d+/

    /(?<=$)d+/.exec('Benjamin Franklin is on the $100 bill')  // ["100"]
    /(?<!$)d+/.exec('it’s is worth about €90')                // ["90"]
    

    上面的例子中,“后行断言”的括号之中的部分((?<=$)),也是不计入返回结果。

    下面的例子是使用后行断言进行字符串替换。

    const RE_DOLLAR_PREFIX = /(?<=$)foo/g;
    '$foo %foo foo'.replace(RE_DOLLAR_PREFIX, 'bar');
    // '$bar %foo foo'
    

    上面代码中,只有在美元符号后面的foo才会被替换。

    “后行断言”的实现,需要先匹配/(?<=y)x/x,然后再回到左边,匹配y的部分。这种“先右后左”的执行顺序,与所有其他正则操作相反,导致了一些不符合预期的行为。

    首先,”后行断言“的组匹配,与正常情况下结果是不一样的。

    /(?<=(d+)(d+))$/.exec('1053') // ["", "1", "053"]
    /^(d+)(d+)$/.exec('1053') // ["1053", "105", "3"]
    

    上面代码中,需要捕捉两个组匹配。没有"后行断言"时,第一个括号是贪婪模式,第二个括号只能捕获一个字符,所以结果是1053。而"后行断言"时,由于执行顺序是从右到左,第二个括号是贪婪模式,第一个括号只能捕获一个字符,所以结果是1053

    其次,"后行断言"的反斜杠引用,也与通常的顺序相反,必须放在对应的那个括号之前。

    /(?<=(o)d1)r/.exec('hodor')  // null
    /(?<=1d(o))r/.exec('hodor')  // ["r", "o"]
    

    上面代码中,如果后行断言的反斜杠引用(1)放在括号的后面,就不会得到匹配结果,必须放在前面才可以。因为后行断言是先从左到右扫描,发现匹配以后再回过头,从右到左完成反斜杠引用。

  • 相关阅读:
    小波变换的引入,通俗易懂
    Leetcode 437. Path Sum III
    Leetcode 113. Path Sum II
    Leetcode 112 Path Sum
    Leetcode 520 Detect Capital
    Leetcode 443 String Compression
    Leetcode 38 Count and Say
    python中的生成器(generator)总结
    python的random模块及加权随机算法的python实现
    leetcode 24. Swap Nodes in Pairs(链表)
  • 原文地址:https://www.cnblogs.com/justart/p/8158531.html
Copyright © 2011-2022 走看看