在RegEx中防止重复匹配

时间:2009-11-04 13:35:28

标签: c# regex unique distinct

以下代码

string expression = "(\\{[0-9]+\\})";
RegexOptions options = ((RegexOptions.IgnorePatternWhitespace | RegexOptions.Multiline) | RegexOptions.IgnoreCase);
Regex tokenParser = new Regex(expression, options);

MatchCollection matches = tokenParser.Matches("The {0} is a {1} and the {2} is also a {1}");

将匹配并捕获“{0}”,“{1}”,“{2}”和“{1}”。

是否可以更改它(正则表达式或RegEx的选项),以便匹配并捕获“{0}”,“{1}”和“{2}”。换句话说,每次匹配只能被捕获一次吗?

4 个答案:

答案 0 :(得分:4)

这是我想出的。

private static bool TokensMatch(string t1, string t2)
{
  return TokenString(t1) == TokenString(t2);
}

private static string TokenString(string input)
{
  Regex tokenParser = new Regex(@"(\{[0-9]+\})|(\[.*?\])");

  string[] tokens = tokenParser.Matches(input).Cast<Match>()
      .Select(m => m.Value).Distinct().OrderBy(s => s).ToArray<string>();

  return String.Join(String.Empty, tokens);
}

请注意,正则表达式与我的问题中的差异是因为我提供了两种类型的令牌;由{}分隔的编号的,由[];

分隔的命名的

答案 1 :(得分:3)

正则表达式解决了很多问题,但不是每个问题。如何在工具箱中使用其他工具?

var parameters = new HashSet<string>(
    matches.Select(mm => mm.Value).Skip(1));

或者

var parameters = matches.Select(mm => mm.Value).Skip(1).Distinct();

答案 2 :(得分:2)

这可以用于纯正则表达式解决方案:

Regex r = new Regex(@"(\{[0-9]+\}|\[[^\[\]]+\])(?<!\1.*\1)",
                    RegexOptions.Singleline);

但是为了效率和可维护性,你可能会更喜欢使用像你发布的那样的混合解决方案。

答案 3 :(得分:-2)

如果您只想要更改一个实例

string expression = "(\\{[0-9]+\\})"; \\one or more repetitions 

string expression = "(\\{[0-9]{1}})";  \\Exactly 1 repetition