【问题标题】:Regex - Match versus Groups正则表达式 - 匹配与组
【发布时间】:2018-04-25 14:04:49
【问题描述】:

如果这属于重复,我很抱歉,但我看不到这些回答了我的问题。

请您帮忙解释一下:

  1. 只有name 的比赛或捕获在哪里举行?模式[A-Za-z0-9_\-\.]+ 的初始部分没有在括号中显示,所以我知道它不会是一个组,那么name 如何被捕获并作为Match 0 的一个组件保存?

  2. 如果我将字符串 t2 替换为 name@domain.com alt@yahoo.net 并将模式替换为 ^([A-Za-z0-9_\-\.\ ]+@(([A-Za-z0-9\-])+\.)+([A-Za-z\-])+)+$

    • 我希望有 2 个匹配项:每个完整的电子邮件地址一个。输出仅显示 1 个匹配项,两者之间用空格隔开,为什么?
    • 应如何读取模式以获得 2 个匹配项,或者该模式的字符串是否需要不同?
    • 我看不到 Group 输出的一致性,因为它没有显示另一个 Group 持有捕获 0=com 和捕获 1=net,类似于 Group 2 持有 domain.yahoo. 捕获,为什么?李>
    • 第 3 组捕获似乎包含第 2 组捕获 0 和 1 的捕获,这是层次结构的工作原理吗?有捕获组的捕获吗?

代码

static void Main(string[] args)
    {
        string t2 = "name@domain.com";
        string p2 = @"^[A-Za-z0-9_\-\.\ ]+@(([A-Za-z0-9\-])+\.)+([A-Za-z\-])+$";

        MatchCollection matches = Regex.Matches(t2, p2);
        GroupCollection gc;
        int groupIndex = 0;
        int matchIndex = 0;
        int captureIndex = 0;

        foreach (Match nextMatch in matches)
        {
            gc = nextMatch.Groups;
            Console.WriteLine("Match {0} holds: {1}", matchIndex, nextMatch.Value);
            matchIndex++;
            foreach (Group g in gc)
            {
                Console.WriteLine("Group {0} holding: {1}", groupIndex, g.ToString());
                groupIndex++;

                foreach (Capture capture in g.Captures)
                {
                    Console.WriteLine("\tCapture {0} holds {1}", captureIndex, capture.ToString());
                    captureIndex++;
                }
                captureIndex = 0;
            }
            groupIndex = 0;
        }
        matchIndex = 0;
    }

上述代码的输出:

Match 0 holds: name@domain.com
Group 0 holding: name@domain.com
Capture 0 holds name@domain.com
Group 1 holding: domain.
Capture 0 holds domain.
Group 2 holding: n
Capture 0 holds d
Capture 1 holds o
Capture 2 holds m
Capture 3 holds a
Capture 4 holds i
Capture 5 holds n
Group 3 holding: m
Capture 0 holds c
Capture 1 holds o
Capture 2 holds m
Press any key to continue . . .

如果字符串t2 = "name@domain.com alt@yahoo.net";和字符串p2 = @"^([A-Za-z0-9_\-\.\ ]+@(([A-Za-z0-9\-])+\.)+([A-Za-z\-])+)+$"则输出;

Match 0 holds: name@domain.com alt@yahoo.net
Group 0 holding: name@domain.com alt@yahoo.net
Capture 0 holds name@domain.com alt@yahoo.net
Group 1 holding:  alt@yahoo.net
Capture 0 holds name@domain.com
Capture 1 holds  alt@yahoo.net
Group 2 holding: yahoo.
Capture 0 holds domain.
Capture 1 holds yahoo.
Group 3 holding: o
Capture 0 holds d
Capture 1 holds o
Capture 2 holds m
Capture 3 holds a
Capture 4 holds i
Capture 5 holds n
Capture 6 holds y
Capture 7 holds a
Capture 8 holds h
Capture 9 holds o
Capture 10 holds o
Group 4 holding: t
Capture 0 holds c
Capture 1 holds o
Capture 2 holds m
Capture 3 holds n
Capture 4 holds e
Capture 5 holds t
Press any key to continue . . .

【问题讨论】:

  • “那么“name”是如何被捕获并保存为 Match 0 的一个组成部分的呢?”:Match 0 是正则表达式匹配的整个字符串。 ^[A-Za-z0-9_\-\.\ ]+ 是正则表达式的一部分,您可以通过查看来观察。因此,它是匹配的。
  • "我希望有 2 个匹配项,每个完整的电子邮件地址一个。" -- 你会这样认为是因为你没有阅读文档并找出^ 的含义。现在去读吧。我投票结束,因为“请大声朗读文档给我听”不是编程问题。
  • @EdPlunkett,感谢您的第一条评论,我可以在我粘贴的输出中看到匹配 0 匹配,但认为它会作为整个匹配 0 的子组件保存在类似的地方对于组/捕获,我推断并在调试中看到,如果这部分在 () 中,它会显示它所在的组,否则它只显示在匹配 0 中。在您的第二条评论中,我在 ^ 上的注释说输入文本的开头,但是如果删除 @"^([A-Za-z0-9_\-\.\ ]+@(([A-Za-z0-9\-])+\.)+([A-Za -z\-])+)+$" 我得到相同的输出,我应该在哪里看?
  • 嗨 @zᴉɹɥƆ 变化很明显,非常感谢您的帮助!

标签: c# regex


【解决方案1】:

Match 涵盖了整个正则表达式的匹配。正则表达式可以应用于给定的字符串。

Groups 是 Match 的一部分,Captures 是(如果您指定了多个像 (someRegex)+ 这样的组的多次出现)所有 Captures 的 Group。尝试将([A-Za-z\-])+ 更改为([A-Za-z\-]+) 看看有什么不同!

例子:

\w*(123)\w*"asdsa123asdf"

  1. 匹配 -> asdsa123asdf
  2. 组 -> 123 (== 最后一次捕获)
  3. 捕获 -> 123

\w*([123])+\w*"asdsa123asdf"

  1. 匹配 -> asdsa123asdf
  2. 组 -> 3 (== 最后一次捕获)
  3. 捕获 -> 1、2、3

有多个站点可以测试并显示您的正则表达式的详细信息,即https://regexr.comhttps://regex101.com

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-13
    • 2022-01-22
    相关资源
    最近更新 更多