在 C# 中使用 .matches .Concat 进行正则表达式和正确捕获

我有以下正则表达式:


@"{thing:(?:((\w)\2*)([^}]*?))+}"

我正在使用它来查找字符串中的匹配项:


MatchCollection matches = regex.Matches(string);

       IEnumerable formatTokens = matches[0].Groups[3].Captures

                                   .OfType<Capture>()

                                   .Where(i => i.Length > 0)

                                   .Select(i => i.Value)

                                   .Concat(matches[0].Groups[1].Captures.OfType<Capture>().Select(i => i.Value));

这曾经产生我想要的结果;然而,我的目标从此改变了。这是现在所需的行为:


假设输入的字符串是'stuff/{thing:aa/bb/cccc}{thing:cccc}'


我希望formatTokens 是:


formatTokens[0] == "aa/bb/cccc"

formatTokens[1] == "cccc"

现在,这就是我得到的:


formatTokens[0] == "/"

formatTokens[1] == "/"

formatTokens[2] == "cccc"

formatTokens[3] == "bb"

formatTokens[4] == "aa"

请特别注意,即使输入了两次,“cccc”也不会出现两次。


我认为问题是 1) 正则表达式中的重新捕获和 2) concat 配置(这是我想要将所有东西分开的时候),但到目前为止我还没有找到能够产生我想要的组合。有人可以阐明正确的正则表达式/concat 组合以产生上述所需的结果吗?


慕森卡
浏览 191回答 2
2回答

哈士奇WWW

您可以使用Regex.Matches(s,&nbsp;@"{thing:([^}]*)}") &nbsp;&nbsp;&nbsp;&nbsp;.Cast<Match>() &nbsp;&nbsp;&nbsp;&nbsp;.Select(x&nbsp;=>&nbsp;x.Groups[1].Value) &nbsp;&nbsp;&nbsp;&nbsp;.ToList()查看正则表达式演示详情{thing:- 文字{thing:子串([^}]*)- 捕获组 #1(当获得匹配时,可以通过 访问其值match.Groups[1].Value):0+ 个字符,而不是}}- 一个}字符。这样,您可以找到多个匹配项,并且只在结果列表/数组中收集第 1 组值。

繁花如伊

模组更新我不确定您为什么选择 Stringnuts 正则表达式,因为它匹配大括号内的任何内容{}。对SO的温顺不会得到深入知识的满足,所以这可能是你真正的问题。让我们分析您的正则表达式。&nbsp;{thing:&nbsp;(?:&nbsp; &nbsp; &nbsp; (&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# (1 start)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;( \w )&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # (2)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;\2*&nbsp;&nbsp; &nbsp; &nbsp; )&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# (1 end)&nbsp; &nbsp; &nbsp; ( [^}]*? )&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # (3)&nbsp;)+&nbsp;}这减少到这个&nbsp;{thing:&nbsp;(?: \w [^}]*? )+&nbsp;}唯一的限制是,紧跟其后{thing:必须有一个词。之后可以有其他任何东西,因为这个子句[^}]*?接受任何东西。此外,即使该子句不贪婪,周围的集群也只会运行一次迭代(?: )+所以,基本上,除了单字要求之外,它几乎什么都不做。您正则表达式可以用于as is获得令人费解的比赛,因为你已经抓住了所有的部分捕获集合,以每场比赛,你可以拼凑一起使用下面的代码。在您继续学习其他东西之前,我会尝试更好地理解正则表达式,因为它可能比用于提取数据的语言技巧重要得多。以下是使用未更改的正则表达式将所有内容拼凑在一起的方法。Regex regex = new Regex(@"{thing:(?:((\w)\2*)([^}]*?))+}");string str = "stuff/{thing:aa/bb/cccc}{thing:cccc}";foreach (Match match in regex.Matches(str)){&nbsp; &nbsp; CaptureCollection cc1 = match.Groups[1].Captures;&nbsp; &nbsp; CaptureCollection cc3 = match.Groups[3].Captures;&nbsp; &nbsp; string token = "";&nbsp; &nbsp; for (int i = 0; i < cc1.Count; i++)&nbsp; &nbsp; &nbsp; &nbsp; token += cc1[i].Value + cc3[i].Value;&nbsp; &nbsp; Console.WriteLine("{0}", token);}输出aa/bb/cccccccc请注意,例如,只要第一个字符是单词,您的正则表达式将匹配大括号内的几乎所有内容。例如,它匹配 {thing:Z,,,*()(((asgassgasg,asgfasgafg\/\=99.239&nbsp; }您可能需要考虑大括号内实际允许的要求。祝你好运!
打开App,查看更多内容
随时随地看视频慕课网APP