PHP: регулярное выражение для игнорирования скрытых кавычек в кавычках
Я просмотрел связанные вопросы, прежде чем публиковать это, и я не смог изменить какие-либо релевантные ответы на работу с моим методом (не хорошо в регулярном выражении).
В принципе, вот мои существующие строки:
$code = preg_replace_callback( '/"(.*?)"/', array( &$this, '_getPHPString' ), $code );
$code = preg_replace_callback( "#'(.*?)'#", array( &$this, '_getPHPString' ), $code );
Оба они соответствуют строкам, содержащимся между ''
и ""
. Мне нужно регулярное выражение, чтобы игнорировать скрытые цитаты, содержащиеся между собой. Таким образом, данные между ''
будут игнорировать \'
, а данные между ""
будут игнорировать \"
.
Любая помощь будет принята с благодарностью.
Ответы
Ответ 1
Для большинства строк вам нужно разрешить что-либо экранированное (а не только экранированные кавычки). например вам, скорее всего, нужно разрешить экранированные символы, такие как "\n"
и "\t"
, и, конечно же, escape-escape: "\\"
.
Это часто задаваемый вопрос, и тот, который был решен (и оптимизирован) давно. Джеффри Фридл подробно рассматривает этот вопрос (в качестве примера) в своей классической работе: Освоение регулярных выражений (3-е издание). Вот регулярное выражение, которое вы ищете:
Хорошо:
"([^"\\]|\\.)*"
Версия 1: работает правильно, но не очень эффективно.
Лучше:
"([^"\\]++|\\.)*"
или "((?>[^"\\]+)|\\.)*"
Версия 2: более эффективна, если у вас есть притяжательные кванторы или атомные группы (см. "Правильный ответ на грех", который использует метод атомной группы).
Лучший:
"[^"\\]*(?:\\.[^"\\]*)*"
Версия 3: еще эффективнее. Реализует технику Friedl: "разворачивание петли". Не требует притяжательных или атомных групп (т.е. Это может использоваться в Javascript и других менее функциональных двигателях с регулярными выражениями.)
Вот рекомендуемые регулярные выражения в синтаксисе PHP для двойных и одинарных кавычек:
$re_dq = '/"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"/s';
$re_sq = "/'[^'\\\\]*(?:\\\\.[^'\\\\]*)*'/s";
Ответ 2
Попробуйте регулярное выражение:
'/"(\\\\[\\\\"]|[^\\\\"])*"/'
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.
Ответ 3
Это, кажется, так же быстро, как развернутый цикл, основанный на некоторых беглых тестах, но гораздо легче читать и понимать. В первую очередь это не требует никакого возврата.
"[^"\\]*(\\.[^"\\]*)*"
Ответ 4
У этого есть возможности:
/"(?>(?:(?>[^"\\]+)|\\.)*)"/
/'(?>(?:(?>[^'\\]+)|\\.)*)'/
Ответ 5
Это оставит кавычки вне
(?<=['"])(.*?)(?=["'])
и использование global
/g будет соответствовать всем группам