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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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