Ниже представлено регулярное выражение PHP, предназначенное для сопоставления (многострочных) строк внутри PHP или исходного кода JavaScript (от этого сообщения), но я подозреваю, что у него возникли проблемы. Что такое буквальный эквивалент Python (или PERL)?
~'(\\.|[^'])*'|"(\\.|[^"])*"~s
re.compile(..., re.DOTALL)
\\.
? Уменьшает ли это до .
? Нужно ли двойным обратным слэшам избегать его дважды в PHP? позволяя в каждой позиции совпадение либо \\.
, либо [^']
(любой символ без кавычек) кажется полным излишеством для меня, может быть, объясняет, почему этот регекс человека взрывается. Группа [^']
не соответствует всем тем, что .
с s-модификатором делает, конечно, он должен соответствовать символам новой строки?
для построения двух версий регулярного выражения с одиночными и двойными кавычками в Python можно использовать этот двухэтапный подход
NB более простая версия этого регулярного выражения также может быть найдена в этом списке примеров регулярного выражения PHP в разделе Programming: String.
Регулярное выражение в основном хорошо, за исключением того, что оно не обрабатывает экранированные кавычки (т.е. \"
и \'
). Это достаточно легко исправить:
'(?:\\.|[^'\\]+)*'|"(?:\\.|[^"\\]+)*"
Это "общее" регулярное выражение; в Python вы обычно записываете его в виде необработанной строки:
r"""'(?:\\.|[^'\\]+)*'|"(?:\\.|[^"\\]+)*""""
В PHP вам нужно избежать обратных косых черт, чтобы получить их после обработки строки PHP:
'~\'(?:\\\\.|[^\'\\\\]+)*\'|"(?:\\\\.|[^"\\\\]+)*"~s'
Большинство популярных в настоящее время языков имеют либо строковый тип, который требует меньше экранирования, поддержка регулярных выражений, так и и то, и другое. Здесь, как ваше регулярное выражение будет выглядеть как строка строки С#:
@"'(?:\\.|[^'\\]+)*'|""(?:\\.|[^""\\]+)*"""
Но, учитывая соображения форматирования, само регулярное выражение должно работать в любом Perl-производном вкусе (и многих других вкусах).
p.s.: Обратите внимание, как я добавил квант +
к вашим классам символов. Ваша интуиция о совпадении одного персонажа за раз правильна; добавление +
имеет огромное значение в производительности. Но не позволяйте этому обмануть вас; когда вы имеете дело с регулярными выражениями, интуиция кажется неправильной чаще, чем нет.:/
\\.
будет соответствовать перед [^']
поэтому он работает нормально. Ваш пункт об улучшении производительности путем добавления +
действителен, но только тогда также необходимо исключить обратную косую черту в классах символов.
"\"
. Во-первых, \\.
Альтернатива соответствует \"
, но это не оставляет ничего для финала "
чтобы соответствовать. Таким образом, он отступает и позволяет альтернативе [^.]
Соответствовать обратной косой черте, а Боб - твой дядя!
\\.
предназначен для соответствия буквальной обратной косой черты в шаблоне и проглатывания следующего символа. Обратите внимание: поскольку шаблоны в PHP (и Python) содержатся в строках, на самом деле это должно быть \\\\.
в строке, так что оно заканчивается как \\.
в регулярном выражении.
Важно сопоставить обратную косую черту и усвоить следующий символ, потому что он может использоваться для исключения цитаты, которая в противном случае закончила бы матч преждевременно.
Этот шаблон выглядит так, как будто он работает нормально, и я не могу придумать более сжатый способ его выразить.
Он также должен хорошо работать в Python (как вы говорите, с re.DOTALL). В Python вы можете использовать нотную строчную нотацию, чтобы сохранить дополнительное экранирование обратной косой черты, хотя вам все равно нужно избегать одиночной кавычки. Это должно быть эквивалентно:
re.search(r'\'(\\.|[^\'])*\'|"(\\.|[^"])*"', str, re.DOTALL)