我正在写一个翻译,而不是任何严肃的项目,只是为了好玩,并且对正则表达式更加熟悉。从下面的代码中我想你可以找出我要去的地方(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);
}
我正在尝试什么,或者有更好的方法来实现这种疯狂吗?
答案 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