排列5走势图首页    注册   登录
排列5走势图 = way to explore
排列5走势图 是一个排列5走势图关于 分享和探索的地方
现在注册
已注册用户请  登录
排列5走势图  ›  程序员

正则表达式 后面不要包含内容 的写法不生效?

  •  
  •   xiangyuecn · 219 天前 · 1497 次点击
    这是一个创建于 219 天前的主题,其中的信息可能已经有所发展或是发生改变。

    昨天学会了如何编写 不要包含指定的字符串内容 的正则表达式写法。

    特意写了一篇文章记录了一下:

    http://www.cnblogs.com/xiangyuecn/p/10668378.html

    里面有一个一直困扰的问题,假设:

    提取<abcdef>\n<abczzz>中首个不包含 def 结尾的 abc 标签,只知道def,不知道zzz


    很简单能写成( v2 页面浏览器控制台测试,但 not only javascript ):

    /<abc(?!def).+>/.exec("<abcdef>\n<abczzz>")


    但往往排列5走势图排列5走势图我 们 不能写死abc,顺理成章的就写成了:

    /<.+(?!def).+>/.exec("<abcdef>\n<abczzz>")


    上面这个不生效,昨天刚发现写成这样就可以了:

    /<(?:.(?!def))+>/.exec("<abcdef>\n<abczzz>")


    不明白为什么.+(?!def)不会生效,前瞻不会和前面的+、*、{}起作用吗?

    第 1 条附言  ·  219 天前

    由于/<.+(?!def).+>/ 结尾还有一个贪婪匹配(虽然实际上只会匹配到结尾仅仅一个字符,看上去像是会匹配所有字符一样,不测试好难看出是哪个.+匹配出来的),这个例子不太好。

    换成#1楼这个例子吧,没这么多干扰:

    /<.+(?!def)zzz>/.exec("<abcdefzzz>\n<abczzz>")

    另注:这里所写的语法,js应该都支持的吧。

        1
    xiangyuecn   219 天前
    又发现另一种有效写法:
    /<(?!.+def).+>/.exec("<abcdefzzz>\n<abczzz>")

    可能是结尾的.+导致的不能匹配,但这样写还是不行:
    /<.+(?!def)zzz>/.exec("<abcdefzzz>\n<abczzz>")
        2
    frank611   219 天前 via Android
    def 后面的.+是不对的,+是必须匹配一个字符或者排列5走势图更多
        3
    binux   219 天前
    /<(.+)(?!def)(.+)>/.exec("<abcdef>\n<abczzz>")
    排列5走势图你 就知道为什么了
        4
    xiangyuecn   219 天前
    @binux 还是不明白,第一个分组捕获到 abcde,预期想要是 abc,前瞻不会和前面的+、*、{}起作用吗?
        5
    binux   219 天前   ♥ 1
    @xiangyuecn #4 别整那么多名词,Matches 'x' only if 'x' is not followed by 'y',排列5走势图你 自己看看"第一个分组捕获到 abcde"还 followed by 'y' 了吗
        6
    zhyl   219 天前 via Android   ♥ 1
    .+ 贪婪匹配
        7
    labnotok   219 天前 via Android
    貌似 js 不支持预查吧,只能手动分组
        8
    xiangyuecn   219 天前
    @binux 还是不太明白,第一个分组的确是捕获到了`abcde`呀,

    照着排列5走势图你 的思路找到 http://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions 的解释中有个例子:
    > >>>>>
    Matches 'x' only if 'x' is not followed by 'y'. This is called a negated lookahead.

    For example, /\d+(?!\.)/ matches a number only if it is not followed by a decimal point. The regular expression /\d+(?!\.)/.exec("3.141") matches '141' but not '3.141'.
    > >>>>>

    发现一个现象:

    符合预期:/(\d+)(?!\.1)/.exec("123.141")
    符合预期:/([^.]+)(?!\.1)/.exec("123.141")
    无效:/(.+)(?!\.1)/.exec("123.141")

    难以理解,最后一个就是排列5走势图我 的写法,咳。。。
        9
    araraloren   219 天前
    js 的正则有些特性不支持: http://www.regular-expressions.info/javascript.html
        10
    xiangyuecn   219 天前
        11
    noqwerty   219 天前   ♥ 1
    排列5走势图你 这个非要用正则的话感觉只能 <(?!.+def>).+> ,排列5走势图你 的写法里 <.+(?!def).+> 第一个.+是贪婪的,会把 def 也包括进去。
        12
    noqwerty   219 天前
    另外测试正则的时候 http://regex101.com/ 很好用
        13
    binux   219 天前   ♥ 1
    @xiangyuecn #8
    /<.+(?!def).+>/.exec("<abcdef>\n<abczzz>")
    第一个 .+ 匹配到了 abcde,之后是 f,不是 def,第二个 .+ 匹配 f,符合正则

    /(.+)(?!\.1)/.exec("123.141")
    第一个 .+ 匹配到了 123.141 ,之后是 EOF 不是 .1,也符合正则
        14
    xiangyuecn   219 天前
    @binux 嗯,原来如此呀,分解一下豁然开朗,哈哈

    意思就是前瞻只能作用于+贪婪匹配到的最后一个字符,并不能阻止+对最后一个字符之前的所有字符进行贪婪匹配。

    /(\d+)(?!\.1)/.exec("123.141") 目测是这样的:
    > 123:\d+贪婪匹配到.为止
    > 12:发现 123.1 不符合(?!\.1),后退一位
    > 没有表达式了,返回 12

    /(.+)(?!\.1)/.exec("123.141") 目测是这样的:
    > 123.141:.+贪婪匹配到结尾
    > 123.141 : 符合(?!\.1)
    > 没有表达式了,返回 123.141

    /(.(?!\.1))+/.exec("123.141") 目测是这样的:
    > 1:.匹配到新的一位
    > 1:123 符合(?!\.1)
    > 12:.匹配到新的一位
    > 12:123.符合(?!\.1)
    > 123:.匹配到新的一位
    > 12:发现 123.1 不符合(?!\.1),后退一位,并退出循环
    > 没有表达式了,返回 12

    如果要对每个字符进行前瞻检查,唯有最后一种写法比较好理解。
        15
    zhyl   219 天前
    试试这个 `<\w+(?!def)(?<!def)\b>`
        16
    xiangyuecn   219 天前
    @zhyl 尽量不要用后瞻,难移植
    排列5走势图关于   ·   FAQ   ·   API   ·   排列5走势图排列5走势图我 们 的愿景   ·   广告投放   ·   感谢   ·   实用小排列5走势图工具   ·   4040 人在线   最高记录 5043   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 24ms · UTC 09:27 · PVG 17:27 · LAX 01:27 · JFK 04:27
    ♥ Do have faith in what you're doing.