Переведите цель этого регулярного выражения PHP для многострочных строк в Python / PERL

1

Ниже представлено регулярное выражение PHP, предназначенное для сопоставления (многострочных) строк внутри PHP или исходного кода JavaScript (от этого сообщения), но я подозреваю, что у него возникли проблемы. Что такое буквальный эквивалент Python (или PERL)?

~'(\\.|[^'])*'|"(\\.|[^"])*"~s
  • s modifier означает, что точка соответствует всем символам, включая новую строку; в Python, что re.compile(..., re.DOTALL)
  • Я полностью не понимаю намерения ведущего \\.? Уменьшает ли это до .? Нужно ли двойным обратным слэшам избегать его дважды в PHP?
  • позволяя в каждой позиции совпадение либо \\., либо [^'] (любой символ без кавычек) кажется полным излишеством для меня, может быть, объясняет, почему этот регекс человека взрывается. Группа [^'] не соответствует всем тем, что . с s-модификатором делает, конечно, он должен соответствовать символам новой строки?

  • для построения двух версий регулярного выражения с одиночными и двойными кавычками в Python можно использовать этот двухэтапный подход

  • NB более простая версия этого регулярного выражения также может быть найдена в этом списке примеров регулярного выражения PHP в разделе Programming: String.

  • 0
    Я просто перечитал вопрос, и теперь я в замешательстве. В этом другом потоке вы искали регулярные выражения, которые могут вызвать зависание или сбой системы, и это регулярное выражение было одним из ответов. Что ты после этого времени? Вы хотите улучшить регулярное выражение или просто хотите выяснить, не увязло ли оно в Python, как в PHP?
  • 0
    @ Алан, этот вопрос означает именно то, что он говорит: объясните намерение этого регулярного выражения PHP этого парня, то есть, что именно с многострочными строками соответствует это регулярное выражение. Вот и все.
Теги:
multiline

2 ответа

1
Лучший ответ

Регулярное выражение в основном хорошо, за исключением того, что оно не обрабатывает экранированные кавычки (т.е. \" и \'). Это достаточно легко исправить:

'(?:\\.|[^'\\]+)*'|"(?:\\.|[^"\\]+)*"

Это "общее" регулярное выражение; в Python вы обычно записываете его в виде необработанной строки:

r"""'(?:\\.|[^'\\]+)*'|"(?:\\.|[^"\\]+)*""""

В PHP вам нужно избежать обратных косых черт, чтобы получить их после обработки строки PHP:

'~\'(?:\\\\.|[^\'\\\\]+)*\'|"(?:\\\\.|[^"\\\\]+)*"~s'

Большинство популярных в настоящее время языков имеют либо строковый тип, который требует меньше экранирования, поддержка регулярных выражений, так и и то, и другое. Здесь, как ваше регулярное выражение будет выглядеть как строка строки С#:

@"'(?:\\.|[^'\\]+)*'|""(?:\\.|[^""\\]+)*"""

Но, учитывая соображения форматирования, само регулярное выражение должно работать в любом Perl-производном вкусе (и многих других вкусах).


p.s.: Обратите внимание, как я добавил квант + к вашим классам символов. Ваша интуиция о совпадении одного персонажа за раз правильна; добавление + имеет огромное значение в производительности. Но не позволяйте этому обмануть вас; когда вы имеете дело с регулярными выражениями, интуиция кажется неправильной чаще, чем нет.:/

  • 0
    Оригинальное регулярное выражение делает обрабатывать кавычки экранированы, в \\. будет соответствовать перед [^'] поэтому он работает нормально. Ваш пункт об улучшении производительности путем добавления + действителен, но только тогда также необходимо исключить обратную косую черту в классах символов.
  • 0
    @ Long Ears: он хорошо работает с правильно сформированными строковыми литералами, но он также соответствует вещам, которые не должны, например, "\" . Во-первых, \\. Альтернатива соответствует \" , но это не оставляет ничего для финала " чтобы соответствовать. Таким образом, он отступает и позволяет альтернативе [^.] Соответствовать обратной косой черте, а Боб - твой дядя!
Показать ещё 2 комментария
2

\\. предназначен для соответствия буквальной обратной косой черты в шаблоне и проглатывания следующего символа. Обратите внимание: поскольку шаблоны в PHP (и Python) содержатся в строках, на самом деле это должно быть \\\\. в строке, так что оно заканчивается как \\. в регулярном выражении.

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

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

Он также должен хорошо работать в Python (как вы говорите, с re.DOTALL). В Python вы можете использовать нотную строчную нотацию, чтобы сохранить дополнительное экранирование обратной косой черты, хотя вам все равно нужно избегать одиночной кавычки. Это должно быть эквивалентно:

re.search(r'\'(\\.|[^\'])*\'|"(\\.|[^"])*"', str, re.DOTALL)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню