V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
lalawow
V2EX  ›  JavaScript

学习 javascript 的正则表达式,看到圆括号这里以后我深深的疑惑了

  •  
  •   lalawow · 2015-08-13 16:44:33 +08:00 · 4160 次点击
    这是一个创建于 3397 天前的主题,其中的信息可能已经有所发展或是发生改变。
    看了一下书的介绍,复杂的正则表达式引入圆括号以后,我就开始觉得找不到它的逻辑了
    所以我相当于现在对正则表达式这里最基本的东西都没弄清楚
    比如match函数什么时候返回一个值,什么时候返回多个值?是怎么去匹配的?
    圆括号的意义不是固定一个子表达式整体?

    "abcd".match(/ab|cd/)
    ["ab"]
    "abcd".match(/(ab|cd)/)
    ["ab", "ab"]
    "abcd".match(/(ab|cd)+/)
    ["abcd", "cd"]
    "abcd".match(/ab|(cd+)/)
    ["ab", undefined]
    "abcd".match(/ab+|cd+/)
    ["ab"]
    "abcd".match(/(ab)+|cd+/)
    ["ab", "ab"]
    "abcd".match(/ab|(cd)+/)
    ["ab", undefined]

    正则表达式有没有哪里有写的比较易懂的文档可以学习?

    谢谢。
    12 条回复    2015-08-14 13:04:15 +08:00
    wh0syourda66y
        2
    wh0syourda66y  
       2015-08-13 16:57:59 +08:00
    建议楼主去玩一下regex golf
    http://regex.alf.nu/
    echo1937
        3
    echo1937  
       2015-08-13 17:47:28 +08:00
    推荐一本书《精通正则表达式》
    napsterwu
        4
    napsterwu  
       2015-08-13 18:34:02 +08:00
    napsterwu
        5
    napsterwu  
       2015-08-13 18:42:46 +08:00
    #1."abcd".match(/ab|cd/)
    无需解释
    #2."abcd".match(/(ab|cd)/)
    事实上这是分组函数,返回的数组:第一个是字符串本身,第二个往后是匹配到的分组
    #3."abcd".match(/(ab|cd)+/)

    #4."abcd".match(/ab|(cd+)/)
    依旧分组,其实能匹配到ab,然而括号决定了你需要的是cd+,字符串里并没有cd+,返回undefined

    #5."abcd".match(/ab+|cd+/)
    无需解释
    #6."abcd".match(/(ab)+|cd+/)
    同分组
    #7."abcd".match(/ab|(cd)+/)
    分组

    事实上如果没有需要从字符串中取出数据的需求,仅仅是验证的话,可以使用test函数。
    napsterwu
        6
    napsterwu  
       2015-08-13 18:46:53 +08:00
    错了 没睡醒 当没看到吧
    cc7756789
        7
    cc7756789  
       2015-08-13 18:54:10 +08:00
    ```javascript
    "zzabcd".match(/zz(ab|cd)/)
    >= ["zzab", "ab"]
    ```

    圆括号中的是被称为小正则,上面的匹配结果中,会返回2个值,第一个值是匹配的完整值,第二个值则是匹配小正则(圆括号)中的值。故为什么JS中 `"abcd".match(/(ab|cd)/) ` 返回了2个ab,因为第一个值代表完整匹配的值,而第二个值代表小正则中的值。

    ```javascript
    "zzab".match(/(zz(ab|cd))/)
    >= ["zzab", "zzab", "ab"]
    ```
    这里最外围又加了一个括号,原理是一样的,返回的值按完整值,小正则,小小正则,依次排列。
    flowfire
        8
    flowfire  
       2015-08-13 21:42:42 +08:00
    本来觉得自己挺清楚的。。。看完糊涂了。。。
    "abcd".match(/(ab|cd)+/)
    这个正则不是应该返回
    ["abcd","ab","cd"]么
    FrankFang128
        9
    FrankFang128  
       2015-08-14 01:17:54 +08:00 via Android
    感觉被你搞复杂了
    msg7086
        10
    msg7086  
       2015-08-14 08:17:53 +08:00
    @flowfire 这个例子其实挺好的。以前从来没想过这个问题倒是。
    首先这里只有一个括号,所以捕捉出来的只会有一个结果。
    那么至于这里,为什么会出现cd而不会出现ab呢?
    说实话我也没找到依据。只觉得这东西应该和贪婪性有关。
    /(ab|cd)+?/就会匹配第一个找到的,而贪婪匹配就会一路测试到最后一个。
    flowfire
        11
    flowfire  
       2015-08-14 11:22:44 +08:00
    @msg7086 然而我要是加上 g 的话就只剩一个结果了是为什么。。。
    ryd994
        12
    ryd994  
       2015-08-14 13:04:15 +08:00 via Android
    @msg7086
    @flowfire
    capture只capture最后一个,或者说会被覆盖
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2503 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 02:43 · PVG 10:43 · LAX 18:43 · JFK 21:43
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.