【问题标题】:Regular expression to select repeating groups选择重复组的正则表达式
【发布时间】:2012-06-15 13:26:02
【问题描述】:

我有一系列遵循特定格式的分组值,并希望使用单个表达式将它们捕获到组中。 例如,我有-group1 -group2 -group3 并尝试使用类似于(-[\s\S]{1,}?) 的东西这基本上允许我将整个字符串捕获到一个组中,但我希望能够分别反向引用每个值。我认为? 会强制它是非贪婪的,因此,将模式匹配分成三个单独的组(例如)。 现在我只是重复引用(-[\s\S]*?),但似乎应该有更优雅的表达。
谢谢!

【问题讨论】:

  • 这有点含糊。您能否展示一些示例文本和预期的分组结果,包括您打算反向引用的内容?
  • 顺便说一句,[\s\S] 说“匹配任何空格或非空格字符”。考虑一下。 ;)

标签: .net regex


【解决方案1】:

你很幸运,因为 C# 是少数支持子表达式捕获的语言之一(如果不是唯一的话)

https://msdn.microsoft.com/en-us/library/system.text.regularexpressions.capture(v=vs.110)

.NET API 可以看如下

 Matches
     Groups (most regex engines stop here)
         Captures (unique for .NET)

从您的问题中不清楚您想要完全匹配什么,但这应该可以帮助您入门。再次询问您是否卡住了。

  string input = "-group1 -group2 ";
  string pattern = @"(-\S*\W){2}";
  foreach (Match match in Regex.Matches(input, pattern))
  {
     Console.WriteLine("Match: {0}", match.Value);
     for (int groupCtr = 0; groupCtr < match.Groups.Count; groupCtr++)
     {
        Group group = match.Groups[groupCtr];
        Console.WriteLine("   Group {0}: {1}", groupCtr, group.Value);
        for (int captureCtr = 0; captureCtr < group.Captures.Count; captureCtr++)
           Console.WriteLine("      Capture {0}: {1}", captureCtr, 
                             group.Captures[captureCtr].Value);
     }                      
  } 

这个输出

Match: -group1 -group2 
   Group 0: -group1 -group2 
      Capture 0: -group1 -group2 
   Group 1: -group2 
      Capture 0: -group1 
      Capture 1: -group2 

如您所见,(Group 1, Capture 0) 和 (Group 1, Capture 1) 提供组的单个捕获(而不是大多数语言中的最后一个)

这个地址我认为你描述为“能够分别反向引用每个值”

(您使用术语反向引用,但我认为您的目标不是替换模式吗?)

【讨论】:

  • +1。我相信这也是他所要求的。顺便说一句,PHP 提供了它的 preg_match_all(...) 函数;使用PREG_SET_ORDER 标志,它返回一个多维数组,第一个数组包含第一个集合,第二个数组包含第二个集合,等等。(其他标志允许不同的表示。)我的猜测是,如果 .NET 和 PHP已经实现了,其他语言也有。
  • @acheong87 好评论,我会将其添加到答案中,以免冒犯其他语言 :) 我从正则表达式专家 Jan Goyvaerts 那里得知 .NET 在这方面是独一无二的,但我不活跃在其他平台上足以支持这一点。
  • @acheong87,这不是一回事。 preg_match_all() 重复应用正则表达式并返回收集的结果,类似于 .NET 的 Matches() 方法。 OP 希望执行 one 匹配,该匹配将消耗整个字符串,然后分解单个捕获。 .NET 为此提供了CaptureCollection,但 PHP 没有等效项。
  • @AlanMoore,啊,我明白了;对于误导性信息,我向@buckley 道歉,我绝对误解了。因此,如果我现在理解正确,.NET 的CaptureCollection 实际上可以将/^hello, (\w+\s*)+$/ 与“hello, john doe”匹配为“john”和“doe”,而 PHP(和其他语言)不能。
  • @AlanMoore 不用担心,我又改了答案
【解决方案2】:

使用 .NET 正则表达式(几乎只有 .NET),您可以使用:

(?:(-\S+)\s*)+

组 1 将包含所有匹配子字符串的列表。

或者在您的情况下,也许只使用 Matches 就足够了:

var re = new Regex(@"-\S+");
var matches = re.Matches(str);

【讨论】:

    【解决方案3】:

    试试这个:

    (-.+?)(\s|$)
    

    您的第一个捕获组将拥有您想要的(-group1-group2 等)。

    如果您想更好地控制在 - 之后允许的内容,请将 .+? 更改为,例如,[a-zA-Z0-9]+? 以仅匹配字母数字字符。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-11-25
      • 1970-01-01
      • 1970-01-01
      • 2010-12-31
      • 1970-01-01
      • 1970-01-01
      • 2011-06-18
      相关资源
      最近更新 更多