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 будет соответствовать всем группам