Определение, который шаблон, подобранный с помощью Regex. Соответствия

Я пишу переводчика, не как любой серьезный проект, только для забавы и стать немного более знакомым с регулярными выражениями. Из кода ниже я думаю, что можно разработать, куда я иду с этим (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);
        }

То, чего я делаю попытку возможный, или являюсь там лучшим способом достигнуть этого безумия?

5
задан Tim Cooper 30 August 2011 в 14:23
поделиться

3 ответа

Вы можете назвать каждую группу захвата в регулярном выражении, а затем запросить значение каждой именованной группы в вашем совпадении. Это должно позволить вам делать то, что вы хотите.

Например, используя приведенное ниже регулярное выражение

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

, вы можете затем извлечь совпадения группы из результата совпадения:

match.Groups["Group1"].Captures
6
ответ дан 14 December 2019 в 08:42
поделиться

У вас другая проблема. Проверьте это:

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) позволит вам это сделать.

1
ответ дан 14 December 2019 в 08:42
поделиться

Использование именованных групп, как говорит Джефф, является наиболее надежным способом.

Вы также можете обращаться к группам по номерам, как они выражены в вашем шаблоне.

(first)|(second)

можно получить доступ с помощью

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

Конечно, если у вас больше скобок, которые вы не хотите включать, используйте оператор без захвата ?:

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

match.Groups[1].Value // also match group 2 -> second
0
ответ дан 14 December 2019 в 08:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: