Допустим, я хочу представить \q (или любой другой конкретный «экранированный символ обратной косой черты»). То есть я хочу сопоставить \q, но не \q, поскольку последний представляет собой обратную косую черту с экранированием обратной косой черты, за которой следует q. Тем не менее, \\q будет соответствовать, поскольку это обратная косая черта с экранированием обратной косой черты, за которой следует q с экранированием обратной косой черты. (Ну, он будет соответствовать \q в конце, а не \ в начале.)
Я знаю, что мне нужен отрицательный взгляд назад, но они всегда связывают мою голову узлами, особенно потому, что сами обратные косые черты должны быть экранированы в регулярном выражении.
он ищет регулярное выражение, которое будет соответствовать одному символу (без пробела?), которому предшествует НЕЧЕТНОЕ количество символов '\'.





Просто напишите простой парсер. Если регулярное выражение связывает вашу голову узлами сейчас, просто подождите месяц.
Фрэнк, мем «теперь у вас 2 проблемы» - это просто (глупая?) Шутка программистов. Регулярные выражения имеют плохую прессу из-за всех идиотов, которые используют их для HTML и XML. В противном случае это допустимый инструмент, если анализируемым содержимым является en.wikipedia.org/wiki/Regular_language. Какие "неэкранированные обратные косые черты" оказываются ...
Лучшее решение - выполнить собственный синтаксический анализ строки, поскольку регулярные выражения на самом деле не поддерживают то, что вы пытаетесь сделать. (представитель @Frank Krueger, если вы пойдете этим путем, я просто повторяю его совет)
Однако я сделал попытку исключительного регулярного выражения. Это будет соответствовать всем строкам, которые не соответствуют вашим критериям символа "\", за которым следует символ.
(?:[\][\])(?!(([\](?![\])[a-zA-Z])))
Обновлено: Мое новое и улучшенное регулярное выражение Perl, поддерживающее более трех обратных косых черт:
/(?<!\) # Not preceded by a single backslash (?>\\)* # an even number of backslashes \q # Followed by a \q /x;
или если ваша библиотека регулярных выражений не поддерживает расширенный синтаксис.
/(?<!\)(?>\\)*\q/
Результат моей тестовой программы:
q does not match \q does match \q does not match \\q does match \\q does not match \\\q does match
Старая версия
/(?:(?<!\)|(?<=\\))\q/
Леон Тиммерманс получил именно то, что искал. Я бы добавил одно небольшое улучшение для тех, кто придет сюда позже:
/(?<!\)(?:\\)*\q/
Дополнительный ?: в начале группы (\\) делает его не сохраненным ни в каких данных матча. Я не могу представить сценарий, в котором я бы хотел сохранить текст этого.
Истинный. Если вы хотите еще лучше, вы можете сделать / (? <! \) (?> \\\) * \\ q / Он имеет немного лучшую производительность в случае несовпадения.
Спасибо, Джеймс, работает шарм. Пример: разделить строку по первому неэкранированному символу двоеточия в Python: re.match(r'(.*?(?<!\)(?:\\)*):(.*)', text).groups(). Работает, как ожидалось, с любым количеством обратных косых черт.
@LeonTimmermans и Джеймс - эй - я придумал выражение, которое, по крайней мере, когда я тестирую его на RegexHero, кажется, на ~ 35-40% быстрее в .Net, если вам интересно: (?<!(?<!\)\(\\)*)\g - это также Только соответствует желаемому символу, а не всему выражению (так что для \\\g он проверит, что \\\ четный номер, затем сопоставит \g - я считаю, что ваш соответствует \\\g - не похоже, что это было желательно (?)
Непонятно, с чем вы пытаетесь сопоставить. Учитывая «\ n», хотите ли вы сопоставить: (1) символ новой строки, (2) последовательность «обратная косая черта, затем n», (3) последовательность «обратная косая черта, затем символ новой строки»?