Самый простой способ построить строку путем интерполяции значений в шаблон Regex? - PullRequest
5 голосов
/ 08 сентября 2011

Я обычно сталкиваюсь с множеством условий и / или циклов для анализа регулярного выражения и интерполяции значений обратно в его группы захвата, и ищу опытные ответы для решения этой проблемы, надеюсь, простым способом.

Например, учитывая шаблон регулярного выражения, например X(?<xid>\d+)-(?<xsub>\w+)\.xml, имеющий именованные группы захвата " xid " и " xsub ", предназначенные для соответствия именам файлов, таким как: X1- foo.xml , X555-bar.xml и т. д., если они снабжены аргументами: int xid=999, string xsub="baz", я хочу интерполировать эти значения в группы шаблонов, чтобы создать правильное имя файла: X999-baz.xml

Для простоты явные захваты не являются вложенными.


без строки. Формат :

Эту концепцию легко реализовать с помощью элементов формата .NET String, таких как String.Format("X{0}-{1}.xml", xid, xsub), однако у меня уже есть шаблон Regex для анализа этих значений из любой строки имени файла, и я хочу использовать этот же шаблон для перехода в противоположном направлении путем восстановления имя файла с ним, для точности. Если мне требуется шаблон регулярного выражения для синтаксического анализа значений из строки, но строка с элементами формата для восстановления имени файла, требуется использовать два вида различных синтаксисов, создавая большую вероятность возникновения ошибки вручную при их написании - это слишком легко ошибочно создать строку элемента плохого формата, которая не восстанавливает должным образом результат сопоставления с шаблоном регулярного выражения, или наоборот.

Ответы [ 2 ]

2 голосов
/ 08 сентября 2011

Вы можете использовать регулярные выражения (yay, мета-регулярные выражения!):

public static string RegexInterp(Regex pattern, Dictionary<string, string> pairs) {
    string regex = pattern.ToString();
    string search;

    foreach(KeyValuePair<string, string> entry in pairs) 
    {
        // using negative lookbehind so it doesn't match escaped parens
        search = @"\(\?<" + entry.Key + @">.*?(?<!\\)\)"; 
        regex  = Regex.Replace(regex, search, entry.Value);
    }

    return Regex.Unescape(unescaped);
}

А затем:

Regex rx = new Regex(@"X(?<xid>\d\d+)-(?<xsub>\w+)\.xml");

var values = new Dictionary <string, string>() {{"xid", "999"},
                                                {"xsub", "baz"}} ;

Console.WriteLine(RegexInterp(rx, values));     

Печать

X999-baz.xml

Демо: http://ideone.com/QwI2W

0 голосов
/ 08 сентября 2011

Возможно, я прочитал это неправильно, но, похоже, вам нужен метод Regex.Replace в пространстве имен System.Text.RegularExpressions.

string pattern = "Your pattern";
string replacement = "Your text to replace";
Regex rgx = new Regex(pattern);
string result = rgx.Replace(input, replacement);

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...