查看: 266|回复: 11
打印 上一主题 下一主题

[讨论] 正则表达式中如何引用带量词的括号分组?

[复制链接]
  • TA的每日心情
    擦汗
    2020-7-3 13:51
  • 签到天数: 19 天

    [LV.4]偶尔看看III

    90

    主题

    277

    回帖

    1万

    积分

    状元

    Rank: 9Rank: 9Rank: 9

    积分
    10032
    跳转到指定楼层
    1
    发表于 2021-3-4 10:26:38 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
    两到三个字母后紧跟两到三个数字,这种组合重复多次(次数不定),匹配出来之后,有无表达方法引用其中匹配到的每个组?

    正则表达式:([a-z]{2,3}\d{2,3})+

    待匹配字符串: 93829before28391ab12fit239rim25pr998rup901he18ke298ryu229after8238

    我需要以某种方式引用以下字符串:  ab12fit239    rim25pr998   rup901he18   ke298ryu229

    貌似\1 \2 这种表达方式是不可以的,因为只有一对括号。这种类似问题来源于我C#编程计中,而不是在notepad++, EmEditor这些编辑器进行的简单操作。谁知道哪种编程语言是支持的呢??这个例子并非最恰当,因为显然可以将正则表达式最后的加号去掉,做多次匹配。然而有时候这个正则表达式相当复杂,做多次匹配时有编程又不方便,如果能一次性整体匹配就可引用这些组最好。
  • TA的每日心情
    奋斗
    2 小时前
  • 签到天数: 1946 天

    [LV.Master]伴坛终老

    0

    主题

    1820

    回帖

    2万

    积分

    状元

    Rank: 9Rank: 9Rank: 9

    积分
    27004

    灌水大神章

    2
    发表于 2021-3-4 13:54:58 | 只看该作者
    本帖最后由 wdscxsj 于 2021-3-5 07:51 编辑

    我觉得不能,原因是组数不定又想直接引用,本身就矛盾。多次匹配是这种情况的自然选择,好像也挺方便的。

    更新:C#对这个需求有直接的支持,见11楼示例;Mastering Regular Expressions 第434~435页也有介绍,作者表示了“mixed feelings about them”。更常见的情况是仅保留group的最后一个匹配,比如Python文档说:If a group matches multiple times, only the last match is accessible。手工加几行逻辑也不麻烦,比如可以用“((?:[a-z]{2,3}\d{2,3}[a-z]{2,3}\d{2,3})+)”作为整组抽取(局部化),再逐一匹配(可以单独实现为subgroup()辅助函数),也许和楼主的思路不同,见下面的Python示例。

  • TA的每日心情
    开心
    2018-8-8 03:13
  • 签到天数: 1 天

    [LV.1]初来乍到

    254

    主题

    4264

    回帖

    7万

    积分

    状元

    Rank: 9Rank: 9Rank: 9

    积分
    79050

    小蜜蜂章笑傲江湖章灌水大神章QQ 章

    QQ
    3
    发表于 2021-3-4 16:19:35 | 只看该作者
    本帖最后由 喬治兄 于 2021-3-4 16:41 编辑

    starmars 兄,您的問題多為語焉不詳,難以窺伺問題的核心,很多問題一般都會有解,不在於數學模型之完善,解題的方法和策略在於你對物理模型的掌握度,當你掌握越多,解題的方法也會越多越完善,還是仔細的陳述您的問題,相信很多網友會提供更好的模式幫你解惑
  • TA的每日心情
    擦汗
    2020-7-3 13:51
  • 签到天数: 19 天

    [LV.4]偶尔看看III

    90

    主题

    277

    回帖

    1万

    积分

    状元

    Rank: 9Rank: 9Rank: 9

    积分
    10032
    4
     楼主| 发表于 2021-3-4 17:27:03 | 只看该作者
    喬治兄 发表于 2021-3-4 16:19
    starmars 兄,您的問題多為語焉不詳,難以窺伺問題的核心,很多問題一般都會有解,不在於數學模型之完善, ...

    哈哈,自认为我的中文描述能力相当强,每个问题都问得非常清楚(至于这个问题是否该问或者问题的难易程度另当别论)。
    请举出例子我还有哪些问题问得不清楚让人不知道我在问什么的?
  • TA的每日心情
    开心
    2018-8-8 03:13
  • 签到天数: 1 天

    [LV.1]初来乍到

    254

    主题

    4264

    回帖

    7万

    积分

    状元

    Rank: 9Rank: 9Rank: 9

    积分
    79050

    小蜜蜂章笑傲江湖章灌水大神章QQ 章

    QQ
    5
    发表于 2021-3-4 18:14:58 | 只看该作者
    starmars 发表于 2021-3-4 17:27
    哈哈,自认为我的中文描述能力相当强,每个问题都问得非常清楚(至于这个问题是否该问或者问题的难易程度 ...

    starmars 兄,真不好意思,在下對正則真不太懂,只是想知道為何資料會如此呈現,而如此處理有何作用,也就動機吧?,若能理解其原由和動機則可能會有人可以提出解決的辦法,畢竟每個人對問題的看法都是不同的,有的問題或許在源頭就處理了,不需後續再多次加工,或死磕那個難解的問題,如此既費體力也可能解的不全面
  • TA的每日心情
    擦汗
    2020-7-3 13:51
  • 签到天数: 19 天

    [LV.4]偶尔看看III

    90

    主题

    277

    回帖

    1万

    积分

    状元

    Rank: 9Rank: 9Rank: 9

    积分
    10032
    6
     楼主| 发表于 2021-3-4 19:45:32 | 只看该作者
    喬治兄 发表于 2021-3-4 18:14
    starmars 兄,真不好意思,在下對正則真不太懂,只是想知道為何資料會如此呈現,而如此處理有何作用,也 ...

    这个问题来源于编程实践,只是我忘记当时具体环境了所以无法描述背景。而且这个问题遇到不止一次了,如果正则表达式引入这种分组的引用方法,我当时的编程可以更简单。。。
  • TA的每日心情
    擦汗
    2020-7-3 13:51
  • 签到天数: 19 天

    [LV.4]偶尔看看III

    90

    主题

    277

    回帖

    1万

    积分

    状元

    Rank: 9Rank: 9Rank: 9

    积分
    10032
    7
     楼主| 发表于 2021-3-4 20:48:41 | 只看该作者
    本帖最后由 starmars 于 2021-3-4 21:02 编辑

    最后一条语句应该是



    不知道网页显示的时候怎么总把后面下标隐藏了,我明明加了就是不显示?!弄了好几次都这样发个图片版的
  • TA的每日心情
    擦汗
    2020-7-3 13:51
  • 签到天数: 19 天

    [LV.4]偶尔看看III

    90

    主题

    277

    回帖

    1万

    积分

    状元

    Rank: 9Rank: 9Rank: 9

    积分
    10032
    8
     楼主| 发表于 2021-3-4 20:50:51 | 只看该作者
    喬治兄 发表于 2021-3-4 18:14
    starmars 兄,真不好意思,在下對正則真不太懂,只是想知道為何資料會如此呈現,而如此處理有何作用,也 ...


    泄一下密:该和尚明明是正则大师,已经制作相当多词库了,那新东方的词根词缀给的他PDF,若是“正则白痴”或者“不大懂”,他怎么做出来MDX词库了? 太谦虚了反过来就是骄傲了
  • TA的每日心情
    开心
    2018-8-8 03:13
  • 签到天数: 1 天

    [LV.1]初来乍到

    254

    主题

    4264

    回帖

    7万

    积分

    状元

    Rank: 9Rank: 9Rank: 9

    积分
    79050

    小蜜蜂章笑傲江湖章灌水大神章QQ 章

    QQ
    9
    发表于 2021-3-4 21:01:02 | 只看该作者
    本帖最后由 喬治兄 于 2021-3-4 21:08 编辑
    starmars 发表于 2021-3-4 20:50
    泄一下密:该和尚明明是正则大师,已经制作相当多词库了,那新东方的词根词缀给的他PDF,若是“正则白痴 ...


    starmars 兄,我真的不懂正則,你說的全是在Excel 上加工而成,真是土法煉鋼
    有的問題一看,就知道在excel 上以怎樣的步驟可以達成,非常的土法,不涉及編程,往往僅用到幾個步驟和函數罷了
  • TA的每日心情
    擦汗
    2020-7-3 13:51
  • 签到天数: 19 天

    [LV.4]偶尔看看III

    90

    主题

    277

    回帖

    1万

    积分

    状元

    Rank: 9Rank: 9Rank: 9

    积分
    10032
    10
     楼主| 发表于 2021-3-4 21:06:50 | 只看该作者
    wdscxsj 发表于 2021-3-4 13:54
    我觉得不能,原因是组数不定又想直接引用,本身就矛盾。多次匹配是这种情况的自然选择,好像也挺方便的。 ...

    “组数不定又想直接引用,本身就矛盾” —— 的确,如果仅仅在notepad++, EmEditor等这些编辑器里进行的简单的正则替换操做,似乎没有什么好方法来表示这些数量都不确定的组。但是一到程序设计,就不一样了!

    显然,高级语言的正则库在匹配成功之后每一个分组都已经确定得到了,既然得到了就有办法让它全部保存起来用于今后的引用。

    这里以C#为例(C#的正则库功能天下第一,论支持完整度超过Python, JavaScript, Perl, Java等所有其他高级语言中的正则库!而且没有哪个语言(包括Python)在Windows上开发图形界面软件有C#方便!希望更多的C#程序员来这个论坛!)。

    见以下简短的程序:

    C#语言中某单个匹配的所有分组用一个GroupCollection对象groups表示,该对象中的每一个成员是一个Group对象,groups[0]表示0号分组,在现有的库下,如果硬要引用带量词(如 + * ? {m,n})的组,那么根据我的实验  MessageBox.Show(groups[0].Value);  这条语句会打印出来所有匹配上的子分组(目前它们都属于\0这同一个“母”分组)的最后一个子分组的值,其他子分组的值无法被引用。

    但是假如我现在拓展C#正则库,在某一个带量词的分组上再设计出一个Subgroups属性来表示所有(而不仅是最后那一个)子分组,我就可以在一个foreach结构里用subgroups来方便地遍历引用所有这些子分组的值。因为我知道所有子分组个数不超过subgroups.Count,我不会发生越界引用的错误。这里只是用MessageBox.Show在屏幕上显示一下子分组的内容而已,但实际编程时可以对已经得到的子分组根据业务需求做各种复杂的处理。

                    Match match = Regex.Match(input, pattern); //match表示一个匹配
                    if (match.Success) // 至少有一个匹配成功
                    {
                        GroupCollection groups = match.Groups; // 获得一个匹配中所有的分组(可以理解为它象是一个数组,每个分量代表一个正则表达式中小括号表示的分组)
                        MessageBox.Show(groups[0].Value); // 显示0号分组的值,因为0号“母”分组带量词(如 + * ? {m,n}),实际对应很多子分组,现行API或者说正则语法无法表示引用每个子分组,结果通过做实验可知这里实际显示的是最后一个子分组的值                  
                        SubgroupCollection subgroups = groups[0].Subgroups; // 获得带量词重复多次的0号"母"分组实际匹配上的所有子分组,可以把它想象成一个数组,每个分量就是一个0号"母"分组的子分组—— 这条语句是我发明的,实际不存在是编译不过去的,
                        for (int i = 0; i < subgroups.Count; i++) // subgroups.Count是0号分组所有子分组的数目 —— 这条语句是我发明的,实际不存在是编译不过去的,
                        {
                            MessageBox.Show(subgroups);  //  显示每个子分组的值 —— 这条语句我发明的,实际不存在是编译不过去的。注意: 因为未知原因,本语句中subgroups后 有一个引用下标死活不在本站网页显示,这里贴一个图片在最后纠正:
                        }
                    }

    有可能,我的这个要求C#已经实现了只是我不知道,或者其他高级语言正则库里有实现的,知道的朋友请告知,多谢!



  • TA的每日心情
    奋斗
    2 小时前
  • 签到天数: 1946 天

    [LV.Master]伴坛终老

    0

    主题

    1820

    回帖

    2万

    积分

    状元

    Rank: 9Rank: 9Rank: 9

    积分
    27004

    灌水大神章

    11
    发表于 2021-3-5 07:10:38 | 只看该作者
    本帖最后由 wdscxsj 于 2021-3-5 09:04 编辑

    C# 的正则表达式支持是不错,你如果多读读文档就找到了。另可参考2楼更新的简单示例。

    https://docs.microsoft.com/en-us ... ection?view=net-5.0

  • TA的每日心情
    擦汗
    2020-7-3 13:51
  • 签到天数: 19 天

    [LV.4]偶尔看看III

    90

    主题

    277

    回帖

    1万

    积分

    状元

    Rank: 9Rank: 9Rank: 9

    积分
    10032
    12
     楼主| 发表于 2021-3-5 21:25:16 | 只看该作者
    wdscxsj 发表于 2021-3-5 07:10
    C# 的正则表达式支持是不错,你如果多读读文档就找到了。另可参考2楼更新的简单示例。

    https://docs.micro ...

    太感谢您了! 怪我没仔细研读文档!这个问题困扰了我很久了,今天总算有了解答,果不其然,C# 正则库早有解决方案了,真是强大啊。有问题再请教,再次表示感谢!