使用Regex.Matches确定匹配的模式

时间:2010-06-24 16:49:27

标签: c# regex

我正在写一个翻译,而不是任何严肃的项目,只是为了好玩,并且对正则表达式更加熟悉。从下面的代码中我想你可以找出我要去的地方(cheezburger有人吗?)。

我正在使用一个字典,该字典使用正则表达式列表作为键,字典值是List<string>,其中包含更多值的替换值。如果我打算这样做,为了弄清楚替补是什么,我显然需要知道关键是什么,我怎样才能找出触发匹配的模式?

        var dictionary = new Dictionary<string, List<string>>
        {                     
            {"(?!e)ight", new List<string>(){"ite"}},
            {"(?!ues)tion", new List<string>(){"shun"}},
            {"(?:god|allah|buddah?|diety)", new List<string>(){"ceiling cat"}},
            ..
        }

        var regex = "(" + String.Join(")|(", dictionary.Keys.ToArray()) + ")";

        foreach (Match metamatch in Regex.Matches(input
           , regex
           , RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture))
        {
            substitute = GetRandomReplacement(dictionary[ ????? ]);
            input = input.Replace(metamatch.Value, substitute);
        }

我正在尝试什么,或者有更好的方法来实现这种疯狂吗?

3 个答案:

答案 0 :(得分:6)

您可以在正则表达式中为每个捕获组命名,然后在匹配中查询每个命名组的值。这应该可以让你做你想做的事。

例如,使用下面的正则表达式

(?<Group1>(?!e))ight

然后,您可以从匹配结果中提取小组匹配项:

match.Groups["Group1"].Captures

答案 1 :(得分:1)

你还有另外一个问题。看看这个:

string s = @"My weight is slight.";
Regex r = new Regex(@"(?<!e)ight\b");
foreach (Match m in r.Matches(s))
{
  s = s.Replace(m.Value, "ite");
}
Console.WriteLine(s);

输出:

My weite is slite.

String.Replace是一个全局操作,因此即使weight与正则表达式不匹配,但在找到slight时它仍会发生变化。您需要同时进行匹配,查找和替换; Regex.Replace(String, MatchEvaluator)会让你这样做。

答案 2 :(得分:0)

使用像Jeff这样的命名组是最强大的方式。

您还可以按编号访问组,因为它们在您的模式中表示。

(first)|(second)
可以使用

访问

match.Groups[1] // match group 2 -> second

当然,如果您有更多您不想包含的括号,请使用非捕获运算符?:

((?:f|F)irst)|((?:s|S)econd)

match.Groups[1].Value // also match group 2 -> second