V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
oakland
V2EX  ›  正则表达式

正则表达式合集帖(希望本帖能存活十年以上)

  •  
  •   oakland · 271 天前 · 4838 次点击
    这是一个创建于 271 天前的主题,其中的信息可能已经有所发展或是发生改变。
    1. 欢迎大家在这篇文章下面评论留言,给出自己在日常 coding 的过程中写过的正则表达式,并给出说明和示例,注明对应的语言,如果能给出如何写出来的详细解释更好。
    2. 欢迎大家留言给出自己想要实现的正则表达式(注明语言),然后群友给 ta 解答。
    3. 欢迎大家“优化”已经留言的正则表达式。
    4. 我希望这篇文章成为所有 “讨厌” 和 “喜爱” 正则表达式的同学的聚集地,并最终能让所有人理解和熟悉正则表达式。
    47 条回复    2024-04-10 00:10:40 +08:00
    zapper
        1
    zapper  
       271 天前
    关于 2 和 3 ,为什么我不去问神奇的 GPT 呢
    Kaiv2
        2
    Kaiv2  
       271 天前   ❤️ 1
    lua 语言,jdtls 取 Class 名称

    %[([%a%$_]?[%.%w%(%)*"+,\\_%[%]%s :%-@<>]*)%]%(jdt://[^%)]+%)

    测试字符 [String](jdt://xxxxxxxx)
    ShinichiYao
        3
    ShinichiYao  
       271 天前   ❤️ 5
    自从有了 ChatGPT 再也不用烦心正则怎么写了
    oakland
        4
    oakland  
    OP
       271 天前
    /^(\+|-)?\d+(\.\d+)?(E(\+|-)?\d+)?$/i

    我先来一个,这个表示所有 JavaScript 中的所有数字格式,可以带正负号,可以是整数,可以是浮点数,可以是带 E|e 的科学计数法格式。比如
    “1”
    “+1”
    “-1”
    “-2.4879983487”
    “2.34E-2”(表示 2.34 * 10^-2 ,也就是 0.0234)
    “2.34e3”(表示 2340)
    oakland
        5
    oakland  
    OP
       271 天前
    @zapper 支持直接粘贴 chatgpt 的回答,也希望大家能帮 chatgpt 找 bug ,但我希望是 4 ,这个对大家作为 programmer 有帮助。
    oakland
        6
    oakland  
    OP
       271 天前
    @Kaiv2 好酷,有空的时候欢迎给出详细的解释
    DavidDee
        7
    DavidDee  
       271 天前
    /^-?\d+(\.\d+)?(e-?\d+)?$/i
    /^-?\d+(\.\d+)?(e[+-]?\d+)?$/i
    @oakland #4 gpt3.5 的答案,不知道对不对
    igeeky
        8
    igeeky  
       271 天前
    # 下面的正则是把用户输入的(无意义)大于 2 个字的重复的内容变成单个. 没想到有什么好的,简单的算法实现. 使用正则就比较简单.(python 代码)
    userInputText = """
    测试测试测试
    哈哈哈哈哈哈哈哈哈哈哈哈
    哈哈哈
    你在干嘛呢?你在干嘛呢?你在干嘛呢?你在干嘛呢?你在干嘛呢?你在干嘛呢?你在干嘛呢?你在干嘛呢?你在干嘛呢?
    """
    import re
    regex = r"(?P<r>.{2,100}?)(?P=r){2,}"
    subst = "\\1"
    outputText = re.sub(regex, subst, userInputText, 0, re.MULTILINE)
    print("## input")
    print(userInputText)
    print("## output:")
    print(outputText)

    # 输出:

    ## input

    测试测试测试
    哈哈哈哈哈哈哈哈哈哈哈哈
    哈哈哈
    你在干嘛呢?你在干嘛呢?你在干嘛呢?你在干嘛呢?你在干嘛呢?你在干嘛呢?你在干嘛呢?你在干嘛呢?你在干嘛呢?

    ## output:

    测试
    哈哈
    哈哈哈
    你在干嘛呢?
    oakland
        9
    oakland  
    OP
       271 天前
    @DavidDee 这个回答不支持开头为 “+” 的这种格式,比如 “+1”,覆盖范围不全
    oakland
        10
    oakland  
    OP
       271 天前
    @igeeky 哈哈哈哈哈哈,你在干嘛呢?你在干嘛呢?测试!测试!
    nagisaushio
        11
    nagisaushio  
       271 天前 via Android
    @oakland .1 似乎表示不了
    nagisaushio
        12
    nagisaushio  
       271 天前 via Android   ❤️ 1
    @oakland 还有三个特殊值 NaN +-Infinity
    nagisaushio
        13
    nagisaushio  
       271 天前 via Android
    @oakland 1. 也表示不了,边界条件还是很多的
    igeeky
        14
    igeeky  
       271 天前   ❤️ 1
    再推荐一个我一直在用的一个正则在线测试编写工具吧: https://regex101.com
    测试效果图:
    https://postimg.cc/XB0GyvM8
    clue
        15
    clue  
       271 天前
    我觉得吧, 一定要把一个复杂的校验用一个正则写出来, 是有强迫症, 也不符合代码高可阅读性的准则

    把各个规则拆开校验, 性能又不会有很大的差距, 看起来还简单易懂, 后面的人改起来也方便
    Rab
        16
    Rab  
       271 天前
    zapper
        17
    zapper  
       271 天前
    @oakland #5
    请不要把 AI 生成的内容发送到这里
    https://v2ex.com/about
    duckyrain
        18
    duckyrain  
       271 天前
    unco020511
        19
    unco020511  
       271 天前
    这种活交给 GPT 就挺好
    rainbowhu
        20
    rainbowhu  
       271 天前   ❤️ 1
    (?<!\w)(err(er)?|fail(ed)?)(?!\w)
    一般会用来高亮日志里的错误
    ShundL
        21
    ShundL  
       271 天前   ❤️ 2
    V2 明令禁止粘贴 AI 回复,我跑这来看你 gpt 生成的回答我为什么不直接问 gpt?
    ae86
        22
    ae86  
       271 天前
    https://www.qaq.dad/posts/regex
    ShundL
        23
    ShundL  
       271 天前
    存活十年?一会儿就好被封号了。。。
    icyalala
        24
    icyalala  
       271 天前
    对于正则这种东西,你觉得 GPT 更可信还是去一个帖子里找到的更可信呢?
    dfkjgklfdjg
        25
    dfkjgklfdjg  
       271 天前
    是[正则大全]( https://any-rule.vercel.app/)不好用了吗……

    - [any-rule - Visual Studio Marketplace]( https://marketplace.visualstudio.com/items?itemName=russell.any-rule)
    - [any-rule - IntelliJ IDEs Plugin | Marketplace]( https://plugins.jetbrains.com/plugin/14162-any-rule)
    zzlit
        26
    zzlit  
       271 天前
    我歪一下,翻页了怎么找呢?
    Rickkkkkkk
        27
    Rickkkkkkk  
       271 天前
    正则真的适合人读吗
    biglion666
        28
    biglion666  
       271 天前   ❤️ 2
    https://ihateregex.io/

    此帖终结??
    danhahaha
        29
    danhahaha  
       271 天前   ❤️ 19
    看标题以为你是来请客,进来才发现你只带了口锅
    wxyrrcj
        30
    wxyrrcj  
       271 天前
    cleanery
        31
    cleanery  
       271 天前
    @danhahaha #29 就是, 与其在这搜, 我为什么不直接问 ai
    qiyilai
        32
    qiyilai  
       271 天前
    能随便手写正则的都是怪物,能随便看懂正则的是大怪物
    malusama
        33
    malusama  
       271 天前
    正则这种东西即使是自己写的一周后都看不懂
    dallaslu
        34
    dallaslu  
       271 天前
    ```regexp
    ^(?=^(?:幺鸡|一筒|幺万|红中|\[二三四五六七八九\]\[条筒万\]){14,17}$)(?=(?:.\*\[鸡条\].\*\[万筒\].\*)|(?:.\*筒.\*\[万条鸡\].\*)|(?:.\*万.\*\[筒条鸡\].\*))(?=.\*\[幺一九中\].\*)(?=^(?:(?:(?(幺鸡|一筒|幺万|红中|\[二三四五六七八九\]\[条筒万\]))\\k{2,3})|(?:幺鸡二条三条|一筒二筒三筒|幺万二万三万|(?:二(?\[条筒万\])三\\k 四\\k)|(?:三(?\[条筒万\])四\\k 五\\k)|(?:四(?\[条筒万\])五\\k 六\\k)|(?:五(?\[条筒万\])六\\k 七\\k)|(?:六(?\[条筒万\])七\\k 八\\k)|(?:七(?\[条筒万\])八\\k 九\\k))|(?:(?(幺鸡|一筒|幺万|红中|\[二三四五六七八九\]\[条筒万\]))\\k))\*(?:(?(幺鸡|一筒|幺万|红中|\[二三四五六七八九\]\[条筒万\]))\\k{2,3})(?:(?:(?(幺鸡|一筒|幺万|红中|\[二三四五六七八九\]\[条筒万\]))\\k{2,3})|(?:幺鸡二条三条|一筒二筒三筒|幺万二万三万|(?:二(?\[条筒万\])三\\k 四\\k)|(?:三(?\[条筒万\])四\\k 五\\k)|(?:四(?\[条筒万\])五\\k 六\\k)|(?:五(?\[条筒万\])六\\k 七\\k)|(?:六(?\[条筒万\])七\\k 八\\k)|(?:七(?\[条筒万\])八\\k 九\\k))|(?:(?(幺鸡|一筒|幺万|红中|\[二三四五六七八九\]\[条筒万\]))\\k))\*$)(?=^(?!(?:.\*(?(幺鸡|一筒|幺万|红中|\[二三四五六七八九\]\[条筒万\]))\\k{3}.\*){4,}).\*$)(?:(?:(?:(?:幺鸡二条三条|一筒二筒三筒|幺万二万三万|(?:二(?\[条筒万\])三\\k 四\\k)|(?:三(?\[条筒万\])四\\k 五\\k)|(?:四(?\[条筒万\])五\\k 六\\k)|(?:五(?\[条筒万\])六\\k 七\\k)|(?:六(?\[条筒万\])七\\k 八\\k)|(?:七(?\[条筒万\])八\\k 九\\k)))|((?(幺鸡|一筒|幺万|红中|\[二三四五六七八九\]\[条筒万\]))\\k{2,3}))\*(?:(?(幺鸡|一筒|幺万|红中|\[二三四五六七八九\]\[条筒万\]))\\k)(?:((?:幺鸡二条三条|一筒二筒三筒|幺万二万三万|(?:二(?\[条筒万\])三\\k 四\\k)|(?:三(?\[条筒万\])四\\k 五\\k)|(?:四(?\[条筒万\])五\\k 六\\k)|(?:五(?\[条筒万\])六\\k 七\\k)|(?:六(?\[条筒万\])七\\k 八\\k)|(?:七(?\[条筒万\])八\\k 九\\k)))|((?(幺鸡|一筒|幺万|红中|\[二三四五六七八九\]\[条筒万\]))\\k{2,3}))\*)$
    ```

    匹配麻将和牌的正则表达式: https://dallas.lu/mahjong-regex/
    chrawsl
        35
    chrawsl  
       271 天前
    简单的正则直接手写,复杂的拆成几个特例写几个子匹配,然后套个 (?: ) 和|就行了
    areschen
        36
    areschen  
       271 天前   ❤️ 1
    🤣我还以为是有人挖坟贴
    aldehyde
        37
    aldehyde  
       271 天前   ❤️ 1
    @dallaslu 日麻有一套比较直观的麻将牌以字符串形式的表达方式。详见 https://tenhou.net/2/
    简单来说,麻将牌种类是索子( s )、筒子( p )、万字( m )、字牌( z ),每种各 9 张,编号 1~9 ,日麻规则有红宝牌记为 0 ( 3 红规则每种数牌的各一张 5 ,或者 4 红规则 2 张红 5 筒子)。举例来说,113479m4688p3s24z3s ,24z 分别对应南北,其他的数牌也很一目了然。在这个规则下对字符串进行解析就相对不需要做到那么复杂。
    回复这个是因为我在想,对于这个需求,设计的时候就不应该直接把汉字弄到判断和牌的这一步来。这样写多少有些杂耍了。而且这样的一长串正则只能做到一个功能,我如果想要计算最快听牌方式就完全不能复用其中的阶段性的结果。
    leonshaw
        38
    leonshaw  
       271 天前
    @oakland 不要用 \d ,用 [0-9]
    oakland
        39
    oakland  
    OP
       271 天前
    @danhahaha 哈哈哈,有锅也有菜。你是带着碗来的,结果没找到合适的菜?
    oakland
        40
    oakland  
    OP
       271 天前
    @nagisaushio 如果要把 “1.” 和 “.1” 都囊括进来,感觉只能取其一
    oakland
        41
    oakland  
    OP
       271 天前
    @clue 认可!能用可读性更高的代码建议用可读性更高的代码,但是这个帖子的目的不是为了强调可读性。
    有些场景只能使用正则表达式,这个帖子为了让会的人炫技,为了让不会的人找到可以求助的地方,看的多了就会了
    oakland
        42
    oakland  
    OP
       271 天前
    @igeeky
    @zapper

    抱歉忘记这一条规则了。不过我理解 ai 生成的内容主要针对的是自然语言和一些具有纯解答性质的文字,不是针对这类的讨论
    oakland
        43
    oakland  
    OP
       271 天前
    @icyalala 都可信,如果你能读懂的话
    oakland
        44
    oakland  
    OP
       271 天前
    @malusama 看的多了就能看懂了
    oakland
        45
    oakland  
    OP
       271 天前
    @leonshaw why ?
    oakland
        46
    oakland  
    OP
       271 天前
    @aldehyde 感谢认真的思考和回复
    oakland
        47
    oakland  
    OP
       260 天前
    我说一下我对于正则表达式的理解,以及 #4 楼的正则表达式是如何写出来的。
    正则表达式是一种线性表达式,它可以表达 concatenation / alternative / repeat 这 3 种类型,但是它不可以表达“递归”,在 Chomsky 语言级别中属于 type-3 这个级别,也就是说它的语法决定了它表达的内容是有限的。

    concatenation 换句话来说就是串行,比如 /ab/ 这个正则表达式表达的就是 a 和 b 连接起来的内容。

    alternative 换句话来说就是并行,也可以说是 “或” 的关系,比如 /a|b/ 表达的就是 a 或者 b 这种模式。

    repeat 就是重复,比如 /a*/ 表达的就是 0 到 无穷多 次的 a 。/a+/ 表示的是 1 到 无穷多次 的 a 。/a?/ 表示的是 0 次或者 1 次 a 。

    以上 3 个规则是正则表达式的核心规则,所有的其他规则都是基于以上 3 个规则的语法糖。

    我最开始学习正则表达式的时候非常害怕就是因为我被太多的语法糖震慑住了。

    我们来先定义一下整数,整数就是至少 0-9 至少显示 1 次,也就是 1 到 无穷多个整数。可以用 /\d+/ 来表示,这里 \d 就是 0-9 的语法糖,另外一种写法就是 [0-9],评论区有人提到了,但是没有说为什么要用第二种语法糖。我也没有理解原因。

    小数就是 “整数.整数” 这样的格式,所以是 /\d+\.\d+/,注意这里 . 前面添加了 \,是因为 . 本身表示任意字符,是一个语法糖,添加 \ 来表达 “.” 的本义。

    同时表达整数或者小数的话,就是 ".整数" 这个部分可以省略,也就是整体可以有 0 次或者 1 次,那么就是 /\d+(\.\d+)?/

    如果是科学计数法的话,就是在刚才的基础上再添加一个 “e 整数.整数” 的格式,且后一个 “.整数” 也可以忽略,就是

    /\d+(\.\d+)?(E\d+)?/i ,这里最后的 i 后缀表示忽略大小写,ignore case

    我们再把 正负号作为可选项添加到这个正则里面就可以得到最终的结论了

    /^(\+|-)?\d+(\.\d+)?(E(\+|-)?\d+)?$/i

    我发表这个帖子的目标就是想让懂正则的人能够把自己的正则炫出来,并能解释清楚,希望不懂正则的人能够理解这种写法。因为我自己学正则的时候就很害怕,我会很希望能看见这样的帖子。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1686 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 16:42 · PVG 00:42 · LAX 08:42 · JFK 11:42
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.