Регулярное выражение, которое игнорирует комментарии - PullRequest
0 голосов
/ 12 октября 2009

, будучи новичком в регулярных выражениях, мне нужна помощь в написании регулярных выражений. Он должен соответствовать определенному шаблону, скажем, «ABC». Но шаблон не должен совпадать, когда он используется в комментарии («знак комментария»). Итак XYZ ' ABC не должно совпадать. x("teststring ABC") также не должно совпадать. Но ABC("teststring ' xxx") должен соответствовать до конца, то есть xxx не обрезается. Также кто-нибудь знает бесплатное приложение Regex, которое вы можете использовать для «отладки» вашего регулярного выражения? У меня часто возникают проблемы с распознаванием того, что случилось с моими попытками. Спасибо!

Ответы [ 10 ]

5 голосов
/ 12 октября 2009

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

Возможно, вам удастся справиться с этим с любым вкусом регулярных выражений, который вы используете, но в целом я думаю, что вам будет проще и удобнее выполнять этот "трудный" путь. Регулярные выражения для регулярных языков, а вложенное что-либо обычно означает, что регулярные выражения не являются хорошей идеей. Современные расширения синтаксиса регулярных выражений означают, что это может быть выполнимо, но это не будет красиво, и вы наверняка не вспомните, что произошло утром. И единственное место, где регулярные выражения терпят неудачу весьма эффектно (даже с современными нерегулярными расширениями), - это анализ вложенных структур - попытка разобрать любые смешанные комментарии, строки в кавычках и круглые скобки быстро превращается в непонятный и не поддерживаемый беспорядок. Не поймите меня неправильно - я фанат регулярных выражений в нужных местах. Это не один из них.

4 голосов
/ 12 октября 2009

Странно, что многие люди рекомендуют свои любимые инструменты, но никто не может решить проблему под рукой. (Я разработчик RegexBuddy, поэтому я не буду рекомендовать какие-либо инструменты.)

Нет хорошего способа сопоставления Y, если только оно не является частью XYZ с одним регулярным выражением. Что вы можете сделать, так это написать регулярное выражение, соответствующее Y и XYZ: Y | XYZ. Затем используйте немного дополнительного кода для обработки совпадений для Y и игнорируйте их для XYZ. Один из способов сделать это с помощью группы захвата: (Y) | XYZ. Теперь вы можете обрабатывать совпадения первой группы захвата. Когда XYZ совпадает, группа захвата ничего не соответствует.

Чтобы сделать это для ваших комментариев в стиле VB, вы можете использовать регулярное выражение:

'.*|(ABC)

Это регулярное выражение совпадает с одинарной кавычкой и всем до конца строки, или ABC. Это регулярное выражение будет соответствовать всем комментариям (включая ABC или нет). Группа захвата будет соответствовать всем вхождениям ABC, кроме тех, что в комментариях.

Если вы хотите, чтобы ваше регулярное выражение пропускало комментарии и строки, вы можете добавить строки к своему регулярному выражению:

'.*|"[^"\r\n]*"|(ABC)
4 голосов
/ 12 октября 2009

Что касается хороших инструментов регулярных выражений, мне действительно нравится RegexBuddy , но это не бесплатно.

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

1 голос
/ 18 сентября 2012

Вот мое решение этой проблемы: 1. Найти магазин все ваши комментарии в хэш 2. Сделайте замену регулярного выражения 3. Верните комментарии в файл

Экономьте свое время: -)

string fileTextWithComments = "Some tetx file contents";

Dictionary<string, string> comments = new Dictionary<string, string>();

// 1. Find a store all your comments in hash
Regex rc = new Regex("(?:/\\*(?:[^*]|(?:\\*+[^*/]))*\\*+/)|(?://.*)");
MatchCollection matches = rc.Matches(fileTextWithComments);

int index = 0;
foreach (Match match in matches)
{
    string key = string.Format("/*Comment#{0}*/", index++);
    comments.Add(key, match.Value);
    fileTextWithComments = fileTextWithComments.Replace(match.Value, key);
}

// 2. Do your regexp replacement
Regex r = new Regex("YOUR REGEXP PATTERN");
fileTextWithComments = r.Replace(fileTextWithComments, "NEW STRING");


// 3. Bring comments back to file :-)
foreach (string key in comments.Keys)
{
    string comment = comments[key];
    fileTextWithComments = fileTextWithComments.Replace(key, comment);
}
1 голос
/ 12 октября 2009

Для разработки NET вы также можете попробовать RegexDesigner , этот инструмент может сгенерировать код (VB / C #) для вас. Это очень хороший инструмент для нас, начинающих Regex.

текст ссылки

1 голос
/ 12 октября 2009

Я считаю, что лучший «отладчик» для регулярных выражений - просто возиться в интерактивной среде, пробуя множество мелких вещей. Для Python ipython отлично; для Ruby, irb, для вещей типа командной строки, sed ...

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

0 голосов
/ 02 февраля 2013

RegEx1: (-user ")(.*?)"

Тема: report -user "test user" -date 1/4/13 -day понедельник -daterange "1/4/13 1/20/13" -

Результат: -user "test user"

Regex2: (-daterange ")(.*?)"

Тема: report -user "test user" -date 1/4/13 -day понедельник -daterange "1/4/13 1/20/13" -

Результат: -daterange "1/4/13 1/20/13"

RegEx3: (-date )(.*?)( -)

Тема: report -user "test user" -date 1/4/13 -day понедельник -daterange "1/4/13 1/20/13" -

Результат: -date 1/4/13 -

RegEx4: (-day )(.*?)( -)

Тема: report -user "test user" -date 1/4/13 -day понедельник -daterange "1/4/13 1/20/13" -

Результат: -day monday -

Сначала найдите значение в кавычках, если оно не найдено, найдите параметр без кавычек. Это предполагает только одно вхождение параметра. Он также ожидает, что команда либо; используйте кавычки для инкапсуляции строки без кавычек внутри, или; используйте любой символ, кроме кавычки, в первой позиции, не встречайте '-' до следующего параметра и используйте завершающий '-' (добавьте его в строку перед регулярным выражением).

0 голосов
/ 12 октября 2009

Если у вас есть Emacs, есть встроенный инструмент для регулярных выражений, который называется "regexp-builder". Я не совсем понимаю специфику вашего вопроса о регулярных выражениях достаточно хорошо, чтобы предложить ответ на этот вопрос.

0 голосов
/ 12 октября 2009

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

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

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

0 голосов
/ 12 октября 2009

Не могли бы вы уточнить? Я прочитал его трижды, и я думаю, что вы хотите сопоставить данный шаблон, когда он выглядит как литерал. Как не как часть комментария или строки.

То, что вы просите, довольно сложно сделать как одно регулярное выражение. Потому что вы хотите пропустить строки. Несколько строк в одной строке усложняют ситуацию.

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

В Perl из-за его вычислительной мощности по регулярному выражению. Предполагая, что @lines - это список строк, которые вы хотите сопоставить, а $ pattern - это шаблон, который вы хотите сопоставить.

@matches =[];
for (@lines){
  $line = $_;
  $line ~= s/"[^"]*?(?<!\)"//g;
  $line ~= s/'.*//g;
  push @matches, $_ if $line ~= m/$pattern/;
}

Первая подстановка находит любой шаблон, который начинается с двойной кавычки и заканчивается первой неэкранированной двойной кавычкой. Использование стандартного escape-символа возврата. Следующая полоса комментариев. Если шаблон все еще совпадает, он добавляет эту строку в список совпадений.

Он не идеален, потому что не может определить разницу между "a\\" и "a\" Первая обычно является допустимой строкой, а вторая - нет. В любом случае, эти замены будут продолжать искать другой ", если один не найден, строка не выбрасывается. Мы могли бы использовать другую замену, чтобы заменить все двойные обратные косые черты чем-то другим. Но это вызовет проблемы, если шаблон" В поисках содержится обратная косая черта.

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