Я просмотрел связанные вопросы, прежде чем публиковать это, и я не мог изменить какие-либо релевантные ответы на работу с моим методом (не очень хорошо при регулярном выражении).
В принципе, вот мои существующие строки:
$code = preg_replace_callback( '/"(.*?)"/', array( &$this, '_getPHPString' ), $code ); $code = preg_replace_callback( "#'(.*?)'#", array( &$this, '_getPHPString' ), $code );
Они оба соответствуют строкам, содержащимся между ''
и ""
. Мне нужно регулярное выражение, чтобы игнорировать скрытые цитаты, содержащиеся между собой. Таким образом, данные между ''
игнорируются \'
и данными между ""
игнорируются \"
.
Любая помощь будет принята с благодарностью.
Для большинства строк вам нужно разрешить что-либо экранированное (а не только экранированные кавычки). например, вам, скорее всего, нужно разрешить экранированные символы типа "\n"
и "\t"
и, конечно же, escape-escape: "\\"
.
Это часто задаваемый вопрос, и тот, который был решен (и оптимизирован) давно. Джеффри Фридл подробно рассматривает этот вопрос (в качестве примера) в своей классической работе: « Освоение регулярных выражений» (3-е издание) . Вот регулярное выражение, которое вы ищете:
"([^"\\]|\\.)*"
Версия 1: работает правильно, но не очень эффективна.
"([^"\\]++|\\.)*"
или "((?>[^"\\]+)|\\.)*"
Версия 2: более эффективна, если у вас есть притяжательные кванторы или атомные группы (см. Правильный ответ греха, который использует метод атомной группы).
"[^"\\]*(?:\\.[^"\\]*)*"
Версия 3: еще эффективнее. Реализует технику Friedl: «разворачивание петли» . Не требует притяжательных или атомных групп (т. Е. Это может использоваться в Javascript и других менее популярных моделях регулярных выражений).
Вот рекомендуемые регулярные выражения в синтаксисе PHP для двух и одинарных кавычек:
$re_dq = '/"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"/s'; $re_sq = "/'[^'\\\\]*(?:\\\\.[^'\\\\]*)*'/s";
Попробуйте регулярное выражение:
'/"(\\\\[\\\\"]|[^\\\\"])*"/'
A (краткое) объяснение:
" # match a `"` ( # open group 1 \\\\[\\\\"] # match either `\\` or `\"` | # OR [^\\\\"] # match any char other than `\` and `"` )* # close group 1, and repeat it zero or more times " # match a `"`
Следующий фрагмент:
<?php $text = 'abc "string \\\\ \\" literal" def'; preg_match_all('/"(\\\\[\\\\"]|[^\\\\"])*"/', $text, $matches); echo $text . "\n"; print_r($matches); ?>
производит:
abc "string \\ \" literal" def Array ( [0] => Array ( [0] => "string \\ \" literal" ) [1] => Array ( [0] => l ) )
как вы можете видеть на Ideone .
Это, похоже, так же быстро, как развернутый цикл, основанный на некоторых беглых тестах, но гораздо легче читать и понимать. В первую очередь это не требует никакого возврата.
"[^"\\]*(\\.[^"\\]*)*"
У этого есть возможности:
/"(?>(?:(?>[^"\\]+)|\\.)*)"/
/'(?>(?:(?>[^'\\]+)|\\.)*)'/
Это оставит котировки вне
(?<=['"])(.*?)(?=["'])
и использование global
/ g будет соответствовать всем группам