捕获了多个组,但仅捕获了最后一个组

时间:2017-03-30 14:17:10

标签: c# regex

我正在尝试使用正则表达式来帮助将以下字符串转换为字典:

{TheKey|TheValue}{AnotherKey|AnotherValue}

像这样:

["TheKey"] = "TheValue"
["AnotherKey"] = "AnotherValue"

要解析字典的字符串,我使用正则表达式:

 ^(\{(.+?)\|(.+?)\})*?$

但它只会捕获最后一组{AnotherKey | AnotherValue}。

如何让它捕获所有组?

我正在使用C#。

或者,是否有更简单的方法来解决这个问题,而不是使用正则表达式?

代码(属性[" PromptedValues"]包含要解析的字符串):

var regex = Regex.Matches(Properties["PromptedValues"], @"^(\{(.+?)\|(.+?)\})*?$");

foreach(Match match in regex) {

    if(match.Groups.Count == 4) {

        var key = match.Groups[2].Value.ToLower();
        var value = match.Groups[3].Value;

        values.Add(key, new StringPromptedFieldHandler(key, value));
     }

}

这被编码为适用于单个值,一旦我能够获取它以捕获多个值,我将会更新它。

3 个答案:

答案 0 :(得分:2)

$表示:匹配必须发生在字符串的末尾,或者在行或字符串末尾的\ n之前。

^表示:匹配必须从字符串或行的开头开始。

阅读本文以获取更多正则表达式语法:msdn RegEx

删除^和$后,你的正则表达式将匹配所有集合你应该阅读:Match.Groups并得到如下内容:

public class Example
{
   public static void Main()
   {
      string pattern = @"\{(.+?)\|(.+?)\}";
      string input = "{TheKey|TheValue}{AnotherKey|AnotherValue}";
      MatchCollection matches = Regex.Matches(input, pattern);

      foreach (Match match in matches)
      {
         Console.WriteLine("The Key: {0}", match.Groups[1].Value);
         Console.WriteLine("The Value: {0}", match.Groups[2].Value);
         Console.WriteLine();
      }
      Console.WriteLine();
   }
}

答案 1 :(得分:0)

你的正则表达式尝试匹配整行。如果使用锚点,您可以获得单独的对:

var input = Regex.Matches("{TheKey|TheValue}{AnotherKey|AnotherValue}");    
var matches=Regex.Matches(input,@"(\{(.+?)\|(.+?)\})");
Debug.Assert(matches.Count == 2);

最好为字段命名:

var matches=Regex.Matches(input,@"\{(?<key>.+?)\|(?<value>.+?)\}");

这允许您按名称访问字段,甚至可以使用LINQ:

var pairs= from match in matches.Cast<Match>()
           select new {
                          key=match.Groups["key"].Value,
                          value=match.Groups["value"].Value
                      };

答案 2 :(得分:0)

或者,您可以使用群组的Captures属性来获取他们匹配的所有时间。

if (regex.Success)
{
    for (var i = 0; i < regex.Groups[1].Captures.Count; i++)
    {
        var key = regex.Groups[2].Captures[i].Value.ToLower();
        var value = regex.Groups[3].Captures[i].Value;
    }
}

这样做的好处是仍然会检查你的整个字符串是否由匹配组成。建议您删除锚点的解决方案会在较长的字符串中找到看似匹配的内容,但如果出现任何错误,则不会失败。