为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C#
慕森卡 2021-08-22 15:23:46
我有以下正则表达式:@"{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 组合以产生上述所需的结果吗?
查看完整描述

2 回答

?
哈士奇WWW

TA贡献1799条经验 获得超6个赞

您可以使用

Regex.Matches(s, @"{thing:([^}]*)}")
    .Cast<Match>()
    .Select(x => x.Groups[1].Value)
    .ToList()

查看正则表达式演示

详情

  • {thing:- 文字{thing:子串

  • ([^}]*)- 捕获组 #1(当获得匹配时,可以通过 访问其值match.Groups[1].Value):0+ 个字符,而不是}

  • }- 一个}字符。

这样,您可以找到多个匹配项,并且只在结果列表/数组中收集第 1 组值。


查看完整回答
反对 回复 2021-08-22
?
繁花如伊

TA贡献2012条经验 获得超12个赞

模组更新


我不确定您为什么选择 Stringnuts 正则表达式,因为它匹配

大括号内的任何内容{}。


对SO的温顺不会得到深入知识的满足,

所以这可能是你真正的问题。


让我们分析您的正则表达式。


 {thing:

 (?:

      (                             # (1 start)

           ( \w )                        # (2)

           \2* 

      )                             # (1 end)

      ( [^}]*? )                    # (3)

 )+

 }

这减少到这个


 {thing:

 (?: \w [^}]*? )+

 }

唯一的限制是,紧跟其后{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))

{

    CaptureCollection cc1 = match.Groups[1].Captures;

    CaptureCollection cc3 = match.Groups[3].Captures;

    string token = "";

    for (int i = 0; i < cc1.Count; i++)

        token += cc1[i].Value + cc3[i].Value;

    Console.WriteLine("{0}", token);

}

输出


aa/bb/cccc

cccc

请注意,例如,

只要第一个字符是单词,您的正则表达式将匹配大括号内的几乎所有内容。


例如,它匹配 {thing:Z,,,*()(((asgassgasg,asgfasgafg\/\=99.239  }


您可能需要考虑

大括号内实际允许的要求。


祝你好运!


查看完整回答
反对 回复 2021-08-22
  • 2 回答
  • 0 关注
  • 190 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信