【问题标题】:Regular Expression Groups in C#C# 中的正则表达式组
【发布时间】:2011-09-16 13:56:00
【问题描述】:

我继承了一个包含以下正则表达式的代码块,我正在尝试了解它是如何获得结果的。

var pattern = @"\[(.*?)\]";
var matches = Regex.Matches(user, pattern);
if (matches.Count > 0 && matches[0].Groups.Count > 1)
    ...

对于输入user == "Josh Smith [jsmith]":

matches.Count == 1
matches[0].Value == "[jsmith]"

...我理解。但后来:

matches[0].Groups.Count == 2
matches[0].Groups[0].Value == "[jsmith]"
matches[0].Groups[1].Value == "jsmith" <=== how?

根据我的理解查看this question,Groups 集合存储了整个比赛以及上一场比赛。但是,上面的正则表达式不是只匹配 [open square bracket] [text] [close square bracket] 那么为什么“jsmith”会匹配?

另外,groups 集合是否总是恰好存储 2 个组:整个匹配和最后一个匹配?

【问题讨论】:

    标签: c# regex


    【解决方案1】:
    • match.Groups[0] 始终与 match.Value 相同,即整个匹配项。
    • match.Groups[1] 是正则表达式中的第一个捕获组。

    考虑这个例子:

    var pattern = @"\[(.*?)\](.*)";
    var match = Regex.Match("ignored [john] John Johnson", pattern);
    

    在这种情况下,

    • match.Value 是 "[john] John Johnson"
    • match.Groups[0] 始终与 match.Value、"[john] John Johnson" 相同。
    • match.Groups[1] 是来自 (.*?) 的捕获组。
    • match.Groups[2] 是来自 (.*) 的捕获组。
    • match.Groups[1].Captures 是另一个维度。

    考虑另一个例子:

    var pattern = @"(\[.*?\])+";
    var match = Regex.Match("[john][johnny]", pattern);
    

    请注意,我们正在连续查找一个或多个带括号的名称。您需要能够分别获取每个名称。输入Captures!

    • match.Groups[0] 始终与 match.Value、"[john][johnny]" 相同。
    • match.Groups[1] 是来自(\[.*?\])+ 的捕获组。在这种情况下与match.Value 相同。
    • match.Groups[1].Captures[0] 与 match.Groups[1].Value 相同
    • match.Groups[1].Captures[1] 是 [john]
    • match.Groups[1].Captures[2] 是 [johnny]

    【讨论】:

    • 这个答案是帮助我把它放在一起的答案(看起来像从投票中,其他人也觉得一样),并且似乎比接受的答案更正确地解决了这个问题。
    【解决方案2】:

    ( ) 充当捕获组。因此,matches 数组包含 C# 在您的字符串中找到的所有匹配项,而子数组包含这些匹配项中的捕获组的值。如果您不想要额外的捕获级别,请删除( )。

    【讨论】:

    • 如果您不想捕获该组,请使用non-capturing groups。 (?:regex)。正则表达式参考:regular-expressions.info/refadv.html
    • 正确的 BrunoLM :: 如果您需要逻辑组但不希望它被捕获。
    【解决方案3】:

    Groups[0] 是您的整个输入字符串。

    Groups[1] 是用括号 (.*?) 捕获的组。您可以将正则表达式配置为仅捕获显式组(创建正则表达式时有一个选项),或使用(?:.*?) 创建非捕获组。

    【讨论】:

      【解决方案4】:

      括号也用于标识一个组,因此匹配 1 是整个匹配,匹配 2 是在方括号之间找到的内容。

      【讨论】:

        【解决方案5】:

        怎么样?答案就在这里

        (.*?)
        

        那是@"[(.*?)]; 的一个子群

        【讨论】:

          猜你喜欢
          • 2011-08-12
          • 2019-10-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-05-25
          • 1970-01-01
          相关资源
          最近更新 更多