Я пишу переводчика, не как любой серьезный проект, только для забавы и стать немного более знакомым с регулярными выражениями. Из кода ниже я думаю, что можно разработать, куда я иду с этим (cheezburger кто-либо?).
Я использую словарь, который использует список регулярных выражений как ключи, и значение словаря является a 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);
}
То, чего я делаю попытку возможный, или являюсь там лучшим способом достигнуть этого безумия?
Вы можете назвать каждую группу захвата в регулярном выражении, а затем запросить значение каждой именованной группы в вашем совпадении. Это должно позволить вам делать то, что вы хотите.
Например, используя приведенное ниже регулярное выражение
(?<Group1>(?!e))ight
, вы можете затем извлечь совпадения группы из результата совпадения:
match.Groups["Group1"].Captures
У вас другая проблема. Проверьте это:
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
- это глобальная операция, поэтому, хотя вес
не соответствует регулярному выражению, он все равно изменяется, когда незначительное
. Вам нужно выполнять сопоставление, поиск и замену одновременно; Regex.Replace (String, MatchEvaluator)
позволит вам это сделать.
Использование именованных групп, как говорит Джефф, является наиболее надежным способом.
Вы также можете обращаться к группам по номерам, как они выражены в вашем шаблоне.
(first)|(second)
можно получить доступ с помощью
match.Groups[1] // match group 2 -> second
Конечно, если у вас больше скобок, которые вы не хотите включать, используйте оператор без захвата ?:
((?:f|F)irst)|((?:s|S)econd)
match.Groups[1].Value // also match group 2 -> second