正则老司机们,正则规则本身重复了很多次怎么缩短? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
wintercoder
V2EX    正则表达式

正则老司机们,正则规则本身重复了很多次怎么缩短?

  •  
  •   wintercoder 2017-02-08 21:37:30 +08:00 2912 次点击
    这是一个创建于 3172 天前的主题,其中的信息可能已经有所发展或是发生改变。

    正则的规则重复若干次的情况,保证分组正常的情况下怎么缩短? 比如 123-456-789-123-

    (\d{3})-(\d{3})-(\d{3})-(\d{3})

    分成 4 个组,但如果不止 4 个就尴尬了,这种怎么缩短?

    地址 http://regexr.com/

    第 1 条附言    2017-02-08 22:42:11 +08:00

    目标:缩短正则式。 目前情况是:6个item,每个item有7个属性,所以我正则是 <td.+>(.+)</td>\s+ 重复了7次(代表一个item有7个属性),然后PHP的preg_match_all() 匹配出6次,循环跑匹配结果。直接看图吧,你们看滚动条就知道目前这样写有点长了。

    17 条回复    2017-02-09 08:45:12 +08:00
    lcdtyph
        1
    lcdtyph  
       2017-02-08 21:53:07 +08:00
    \d{3}(-\d{3}){3}
    aploium
        2
    aploium  
       2017-02-08 22:06:40 +08:00
    mark 同问 (ls 的好像不行啊)


    如果只是题中的简单情形,可以用(python) re.finditer
    ```
    for m in re.finditer("(\d+)-","123-456-789-123-"):
    print(m.groups())
    ###
    ('123',)
    ('456',)
    ('789',)
    ('123',)
    ```

    但是对于复杂一点的, 比如 cat-123-456-789-123-dog
    :(
    aploium
        4
    aploium  
       2017-02-08 22:09:47 +08:00
    lz 的意思应该是如何只写一个括号, 但是使得 \1 \2 \3 \4 都出现, 并且是对应的匹配值
    wintercoder
        5
    wintercoder  
    OP
       2017-02-08 22:27:26 +08:00
    @rudy1224 #3 关键是不能按我要的分组,(?:)是不分组版本。 我问题的第二个图也能匹配,但没法按图 1 分组。
    wintercoder
        6
    wintercoder  
    OP
       2017-02-08 22:34:28 +08:00
    @aploium #2 我 PHP 的,虽然也有 preg_match_all()来一直匹配下去,但我遇到的是上图的情况本身只是一个小节,这种函数没法嵌套
    如: 3 个 iem ,每个小组是一个属性。
    123-456-789-123-
    432-213-421-321-
    333-512-954-432-
    这样。
    目前我的处理是写很长的(\d{3})-(\d{3})-(\d{3})-(\d{3})这种重复了 7 次,然后 preg_match_all 后循环一层去按这个分组搞...
    就是想看能不能简化那重复 7 次的正则,好长...
    wintercoder
        7
    wintercoder  
    OP
       2017-02-08 22:37:27 +08:00
    @aploium #4 写几个括号都行,只要能正确分组,且比我现在的短,我现在的正则是<td.+>(.+)<\/td>\s+ 重复了 7 次(代表一个 item 有 7 个属性),然后匹配 n 次( n 个 item )...
    vincentxue
        8
    vincentxue  
       2017-02-08 22:43:30 +08:00
    如果我没理解错的话,你要的是:

    (\d{3}-)\1{2,}
    vincentxue
        9
    vincentxue  
       2017-02-08 22:49:13 +08:00
    又看了一遍题目,应该是: (\d{3}-){4,}

    上面那个只匹配相同的.
    wintercoder
        10
    wintercoder  
    OP
       2017-02-08 22:49:17 +08:00
    @vincentxue #8 \1 这种是完全等于分组内容,只能处理 123-123-123-123-,没法搞每组不同的 123-456-789-123-
    wintercoder
        11
    wintercoder  
    OP
       2017-02-08 22:50:16 +08:00
    @vincentxue #9 这是我主题图 2 的内容,能匹配但没法按预期的分组
    SoloCompany
        12
    SoloCompany  
       2017-02-08 23:33:02 +08:00
    不能

    capture group 无法重复,只能返回最后一个匹配的结果
    所以 /(\d{3}-){4}/ 是不 work 的,只能返回最后一个匹配到的分组

    正确姿势应该是用 /\d{3}-/g 然后连续的 match

    js 示例
    r = /\d{3}-/g
    s = '123-456-789-123-‘

    > r.exec(s)[0]
    '123-'
    > r.exec(s)[0]
    '456-'
    > r.exec(s)[0]
    '789-'
    > r.exec(s)[0]
    '123-'
    > r.exec(s)[0]
    exception (exec return null)
    wintercoder
        13
    wintercoder  
    OP
       2017-02-08 23:40:18 +08:00
    @SoloCompany #12 看来还是只能写长了= =!你看我的主题附加的情况,这样一个个叠还真不如写长一次。
    SoloCompany
        14
    SoloCompany  
       2017-02-08 23:40:57 +08:00   2
    @wintercoder 难道不能用程序自动生成正则???
    wintercoder
        15
    wintercoder  
    OP
       2017-02-08 23:43:04 +08:00
    @SoloCompany #14 这解法 666 写个循环替代手写长字符串 可行
    DiamondbacK
        16
    DiamondbacK  
       2017-02-08 23:54:52 +08:00
    #14 结束话题。
    顺便,这属于元编程范式吧。
    imn1
        17
    imn1  
       2017-02-09 08:45:12 +08:00
    一个二维数据矩阵,也可以看作一维数列,只要顺序正确
    你可以用两重循环按矩阵读取,也可以按数列读取,只是最终表现格式如何调整而已
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1120 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 31ms UTC 17:56 PVG 01:56 LAX 10:56 JFK 13:56
    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