【问题标题】:Grouping string by comma between brackets通过括号之间的逗号对字符串进行分组
【发布时间】:2010-04-16 08:50:17
【问题描述】:

回复:Regular Expression to find a string included between two characters while EXCLUDING the delimiters

嗨,我正在寻找适用于我的字符串的正则表达式模式,包括括号:

[1,2,3,4,5] [abc,ef,g] [0,2,4b,y7]
可以是任何东西,包括单词、数字、非单词一起或分开。

我希望通过 \[(.*?)\] 获得括号内的组 但是什么是正则表达式模式,它将给我括号之间的组和用逗号分隔的子组字符串,以便结果可能如下??

组 1 : 1,2,3,4,5 组 1:1 第 2 组:2 第 3 组:3 第 4 组:4 第 5 组:5 组2:abc,ef,g 第一组:abc 组2:ef 组 3:g ETC ..

感谢您的帮助

【问题讨论】:

  • 必须使用RegEx有什么特别的原因吗?
  • 问题乍一看似乎更容易,因为答案确实是使用字符串操作。如果可能的话,我正在寻找另一种方法来解决我的正则表达式问题。我必须使用 RegEx 有一个特殊的原因,因为我应该更具体地理解 RegEx,而不是使用字符串方法。

标签: c# regex


【解决方案1】:

我同意 @Dav 的观点,您最好在每个方括号组上使用 String.Split。

但是,您可以使用单个正则表达式提取所有数据:

(?:\s*\[((.*?)(?:,(.+?))*)\])+

使用此表达式,您必须处理每个group 的所有captures 以获取所有数据。例如,在您的字符串上运行以下代码:

var regex = new Regex(@"(?:\s*\[((.*?)(?:,(.+?))*)\])+");
var match = regex.Match(@"[1,2,3,4,5] [abc,ef,g] [0,2,4b,y7]");

for (var i = 1; i < match.Groups.Count; i++)
{
    var group = match.Groups[i];
    Console.WriteLine("Group " + i);

    for (var j = 0; j < group.Captures.Count; j++)
    {
        var capture = group.Captures[j];

        Console.WriteLine("  Capture " + j + ": " + capture.Value 
                                       + " at " + capture.Index);
    }
}

这会产生以下输出:

第 1 组 捕获 0:1、2、3、4、5 在 1 捕获 1: abc,ef,g 在 13 捕获 2:0,2,4b,y7 在 24 第 2 组 捕获 0:1 到 1 捕获 1: abc 在 13 捕获 2:24 时的 0 第 3 组 捕获 0:2 到 3 在 5 点捕获 1:3 捕获 2:4 到 7 捕获 3:5 在 9 捕捉 4: ef 在 17 捕获 5:g 为 20 捕获 6:2 在 26 捕获 7:28 时的 4b 捕获 8:y7 在 31

第 1 组为您提供每个方括号组的值,第 2 组为您提供每个方括号组中匹配的第一个项目,第 3 组为您提供所有后续项目。您必须查看捕获的索引以确定哪个项目属于每个方括号组。

【讨论】:

  • 捕获组并合并结果。这是一种方法,看起来是唯一的方法。我接受您的回复。谢谢。
【解决方案2】:

这是另一个使用 CaptureCollections 的选项(在单个正则表达式中执行此操作的唯一方法)。 Phil Ross 的答案在一次匹配操作中完成了所有操作,而这一操作进行了多次匹配。这样,所有的单个项目捕获都会根据它们所在的括号对正确分组。

string s = @"[1,2,3,4,5] [abc,ef,g] [0,2,4b,y7] ";
Regex r = new Regex(@"\[((?:([^,\[\]]+),?)*)\]");
int matchNum = 0;
foreach (Match m in r.Matches(s))
{
  Console.WriteLine("Match {0}, Group 1: {1}", ++matchNum, m.Groups[1]);
  int captureNum = 0;
  foreach (Capture c in m.Groups[2].Captures)
  {
    Console.WriteLine("  Group 2, Capture {0}: {1}", ++captureNum, c);
  }
}

输出:

第 1 场比赛,第 1 组:1,2,3,4,5 第 2 组,捕获 1:1 第 2 组,捕获 2:2 第 2 组,捕获 3:3 第 2 组,捕获 4:4 第 2 组,捕获 5:5 第 2 场比赛,第 1 组:abc,ef,g 第 2 组,捕获 1:abc 第 2 组,捕获 2:ef 第 2 组,捕获 3:g 第 3 场比赛,第 1 组:0,2,4b,y7 第 2 组,捕获 1:0 第 2 组,捕获 2:2 第 2 组,捕获 3:4b 第 2 组,捕获 4:y7

【讨论】:

    【解决方案3】:

    你最好在你的组上使用String.Split,一旦你有括号分隔的组来拆分它们。

    【讨论】:

      【解决方案4】:

      \[(.*?)\] 会告诉你括号之间是什么,但如果你添加:

      \[(?<NumSequence>.*?)\]
      

      这将分配一个您可以参考的组。

      编辑 然后我会使用 Phil 的 Reg Ex,因为我上面展示了如何分配一个组。

      【讨论】:

        【解决方案5】:

        我认为您所要求的内容不可能在单个正则表达式中完成。您的数据似乎在括号之间有可变数量的逗号分隔条目,并且没有具有可变数量的捕获组的正则表达式。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-12-02
          • 2018-04-14
          • 2017-08-24
          • 1970-01-01
          • 1970-01-01
          • 2016-04-12
          • 1970-01-01
          • 2013-02-20
          相关资源
          最近更新 更多