学习 Javascript 的正则表达式,看到圆括号这里以后我深深的疑惑了 - V2EX
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 4615 次点击
    这是一个创建于 3716 天前的主题,其中的信息可能已经有所发展或是发生改变。
    看了一下书的介绍,复杂的正则表达式引入圆括号以后,我就开始觉得找不到它的逻辑了
    所以我相当于现在对正则表达式这里最基本的东西都没弄清楚
    比如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
    推荐一本书《精通正则表达式》
    orcusfox
        4
    orcusfox  
       2015-08-13 18:34:02 +08:00
    orcusfox
        5
    orcusfox  
       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函数。
    orcusfox
        6
    orcusfox  
       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     Solana     1354 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 33ms UTC 23:59 PVG 07:59 LAX 16:59 JFK 19:59
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86