регулярное выражение для сопоставления содержимого строки до комментария - PullRequest
1 голос
/ 07 июня 2011

Я пытаюсь сопоставить выражения, содержащиеся в [%___%] в строке, до // (комментарии), исключая // в кавычках (внутри строки)
так например
[%tag%] = "a" + "//" + [%tag2%]; //[%tag3%]
должно соответствовать [%tag%] и [%tag2%]

Самое близкое, что я могу получить, это ^(?:(?:\[%([^%\]\[]*)%\])|[^"]|"[^"]*")*?(?://)

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

И во-вторых, захватывает только второй тег. Это не из-за "//", так как даже с [%1%] [%2%] он не будет захватывать первые

Я использую C # и Regex.Matches с опцией RegexOptions.Multiline, и это моя экранированная строка

"^(?:(?:\\[%([^%\\]\\[]*)%\\])|[^\"]|\"[^\"]*\")*?(?://)"

Ответы [ 2 ]

2 голосов
/ 07 июня 2011

Прежде всего, позвольте мне сказать, что я люблю регулярные выражения.Я прочитал Освоение регулярных выражений Фридла года назад и никогда не оглядывался назад.При этом не используйте одно гигантское регулярное выражение для решения этой проблемы.Используйте свой язык программирования.В итоге вы получите более читаемый и поддерживаемый код.Похоже, вы пытаетесь разобрать язык здесь, где разные правила применяются в разных контекстах.Ваш шаблон может появиться в строке в кавычках.Строки в кавычках могут содержать кавычки, которые необходимо экранировать.Захватить все тонкости в одном регулярном выражении было бы кошмаром.Я рекомендую перебирать строковые символы за символом, собирать токены по пути, искать кавычки и следить за тем, находитесь ли вы в строке в кавычках.Когда вы встретите токен, который соответствует вашим критериям (вы можете использовать регулярное выражение для этой части), и вы не в строке, добавьте его в свой список.Когда вы достигнете конца оператора и встретите начало комментария, отбросьте оставшиеся символы до конца комментария.

1 голос
/ 07 июня 2011

Я думаю, что сделать это за один выстрел немного сложно из-за сложности проверки двойных кавычек.Вы можете сделать это в два этапа:

¤ Удаление всех соответствующих двойных кавычек¤ Поиск вашего шаблона

Regex re1 = new Regex(@"""[^""]*""", RegexOptions.Multiline);
Regex re2 = new Regex(@"(?<!//.*)\[%\w+%\]", RegexOptions.Multiline);
string input = @"[%tag%] = ""a"" + ""//"" + [%tag2%]; //[%tag3%]
[%tag%] = ""a"" + ""ii//"" + [%tag2%]; //[%tag3%]";

MatchCollection ms = re2.Matches(re1.Replace(input, ""));
...