Чтобы удвоить побег или не удвоить бегство в функциях PHP PCRE?

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

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

/\n/ /domain\.com/ /myfeet \$ your feet/ 

Ничего плохого в этом нет? Хорошо, давайте использовать эти примеры в контексте функции preg_match PHP:

 $foo = preg_match("/\n/", $bar); $foo = preg_match("/domain\.com/", $bar); $foo = preg_match("/myfeet \$ your feet/", $bar); 

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

Будет ли предыдущее быть похожим на последующее, и не вызывает ли это ошибки ?:

 $foo = preg_match("/n/", $bar); $foo = preg_match("/domain.com/", $bar); $foo = preg_match("/myfeet $ your feet/", $bar); 

Что не то, что я хочу? эти выражения не совпадают с приведенными выше.

Разве мне не пришлось бы писать им двойное спасение?

 $foo = preg_match("/\\n/", $bar); $foo = preg_match("/domain\\.com/", $bar); $foo = preg_match("/myfeet \\$ your feet/", $bar); 

Так что, когда PHP обрабатывает строку, она пропускает обратную косую черту в обратную косую черту, которая затем остается в том случае, когда она передается интерпретатору PCRE?

Или PHP просто волшебным образом знает, что я хочу передать эту обратную косую черту в интерпретатор PCRE … я имею в виду, как он знает, что я не пытаюсь \" избежать цитаты, которую я хочу использовать в своем выражении», или просто двойной нужно ли использовать TRIPLE для цитаты? \\\" Вы знаете, так что цитата сбежала, а двойной остался?

Что такое эмпирическое правило?

Я просто сделал тест с PHP:

 $bar = "asdfasdf a\"ONE\"sfda dsf adsf me & mine adsf asdf asfd "; echo preg_match("/me \$ mine/", $bar); echo "<br /><br />"; echo preg_match("/me \\$ mine/", $bar); echo "<br /><br />"; echo preg_match("/a\"ONE\"/", $bar); echo "<br /><br />"; echo preg_match("/a\\\"ONE\\\"/", $bar); echo "<br /><br />"; 

Вывод:

 0 1 1 1 

Итак, похоже, почему-то это не имеет значения для котировок, но для знака доллара требуется двойной побег, как я думал.

Строки с двойными кавычками

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

Если соседний символ находится в наборе ntrvef\$" или если после него следует числовое значение ( здесь можно найти правила), он оценивается как соответствующий управляющий символ или порядковое (шестнадцатеричное или восьмеричное) представление соответственно.

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

Например, "domain\.com" будет оставлен как есть.

Обратите внимание, что переменные также расширяются внутри двойных кавычек, например, "$var" необходимо экранировать как "\$var" .

Одиночные кавычки

Начиная с PHP 5.1.1, любая обратная косая черта внутри одиночных кавычек (и за ними следует хотя бы один символ) будет напечатана как есть, и никакие переменные не будут заменены. Это, безусловно, самая удобная особенность одиночных кавычек.

Обычные выражения

Для ускорения регулярных выражений лучше оставить preg_quote() для preg_quote() :

 $foo = preg_match('/' . preg_quote('mine & yours', '/') . '/', $bar); 

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

См. Также: preg_quote

Обновить

Вы добавили этот тест:

 "/me \$ mine/" 

Это оценивается как "/me $ mine/" ; но в PCRE значение $ имеет особое значение (это привязка конца объекта).

 "/me \\$ mine/" 

Это оценивается как "/me \$ mine/" и поэтому обратная косая черта сбрасывается для самого PHP, а $ – для PCRE. Это работает только случайно.

 $var = 'something'; "/me \\$var mine/" 

Это оценивается как "/me \something" , поэтому вам нужно снова избежать $ .

 "/me \\\$var mine/" 

Используйте одинарные кавычки. Они предотвращают появление escape-последовательностей.

Например:

 php > print "hi\n"; hi php > print 'hi\n'; hi\nphp > 

Всякий раз, когда у вас есть некорректная escape-последовательность, PHP фактически оставляет символы буквально в строке. Из документации :

Как и в одиночных кавычках, экранирование любого другого символа приведет к тому, что обратная косая черта также будет напечатана.

Т.е. "\&" действительно интерпретируется как "\&" . Существует не так много escape-последовательностей, поэтому в большинстве случаев вы, вероятно, избегаете одной обратной косой черты. Но для согласованности побег с обратной косой чертой может быть лучшим выбором.

Как всегда: знайте, что вы делаете 🙂

OK Итак, я сделал еще несколько тестов и обнаружил ПРАВИЛО ТОМЫ при инкапсуляции PCRE в DOUBLE QUOTES, выполняется следующее:

$ – Требуется двойной escape, потому что PHP будет интерпретировать это как начало переменной, если текст сразу же следует за ней. Слева безвозвратно, и это покажет конец вашей иглы и сломается.

\r\n\t\v – Специальные escape-строки PHP, требуется только один escape.

[\^$.|?*+() – Специальные символы RegEx, требуется только один выход. Двойной побег, похоже, не нарушает выражения при ненужном использовании.

" Котировки, очевидно, должны быть экранированы из-за инкапсуляции, но нужно только один раз убежать.

\ – Поиск обратной косой черты? Используя инкапсуляцию двойного кавычки вашего выражения, это потребует 3 побегов! \\ (всего четыре обратных косых черты)

Что-нибудь мне не хватает?