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

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

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

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

  • NB. Более простую версию этого регулярного выражения можно также найти в этом списке примеров регулярных выражений PHP, в разделе Программирование: String .

Ответы [ 2 ]

2 голосов
/ 10 августа 2011

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

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

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

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

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

1 голос
/ 10 августа 2011

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

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

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

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

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

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

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

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

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


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

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