php[tek] 2018 : Call for Speakers

Экранирующие последовательности

Обратная косая черта ('\') имеет несколько применений. Прежде всего, если она предшествует не буквенно-цифровому символу, она снимает с него специальное значение, которое он мог иметь. Применение обратной косой черты как экранирующего символа допустимо как в символьном классе, так и вне него.

Например, если вы хотите задать соответствие символу "*", в шаблоне необходимо указать "\*". Это предотвратит трактование последующего символа как метасимвола с особым значением. Всегда безопасно экранировать не буквенно-цифровые символы с помощью "\", если вы хотите убедиться, что они означают в шаблоне самих себя. В частном случае для сопоставления с самим символом обратной косой черты, используйте запись "\\".

Замечание:

PHP-строки, заключенные в одинарные и двойные кавычки, интерпретируют обратную косую черту по-разному. Поэтому, если необходимо совпадение \ с регулярным выражением \\, в PHP-коде нужно использовать "\\\\" или '\\\\'.

В случае, если указан модификатор PCRE_EXTENDED, пробельные символы в шаблоне (вне описания символьного класса) игнорируются. Также игнорируется часть строки, находящаяся между символом "#" (опять же, не участвующем в описании символьного класса) и следующим символом перевода строки. В таком случае обратный слеш можно применять как экранирующий символ для указания вхождений пробельных символов или символа "#" в шаблоне.

Второе применение обратного слеша заключается в том, что он позволяет использовать непечатные символы в видимой форме в описании шаблона. При том, что в PCRE нет ограничений на использование непечатных символов (исключая бинарный ноль, который интерпретируется как конец шаблона), при редактировании программного кода в каком-либо текстовом редакторе гораздо удобнее использовать следующие комбинации, чем реальные символы, которые они представляют:

\a
символ оповещения, сигнал, (BEL, шестнадцатеричный код 07)
\cx
"Ctrl+x", где x - произвольный символ
\e
escape (шестнадцатеричный код 1B)
\f
разрыв страницы (шестнадцатеричный код 0C)
\n
перевод строки (шестнадцатеричный код 0A)
\p{xx}
символ со свойством xx, подробнее смотрите свойства unicode
\P{xx}
символ без свойства xx, подробнее смотрите свойства unicode
\r
возврат каретки (шестнадцатеричный код 0D)
\R
разрыв строки: совпадает с \n, \r и \r\n
\t
табуляция (шестнадцатеричный код 09)
\xhh
символ с шестнадцатеричным кодом hh
\ddd
символ с восьмеричным кодом ddd, либо ссылка на подмаску

Если быть более точным, комбинация "\cx" интерпретируется следующим образом: если "x" - символ нижнего регистра, он преобразуется в верхний регистр. После этого шестой бит символа (шестнадцатеричный код 40) инвертируется. Таким образом "\cz" интерпретируется как шестнадцатеричное значение 1A, в то время как "\c{" получает шестнадцатеричное значение 3B, а "\c;" - 7B.

После "\x" считываются еще две шестнадцатеричные цифры (они могут быть записаны в нижнем или верхнем регистре). В режиме UTF-8, разрешается использование "\x{...}", где содержимое скобок является строкой из шестнадцатеричных цифр. Она интерпретируется как символ UTF-8 character с кодом, совпадающим с данным шестнадцатеричным числом. Исходная шестнадцатеричная экранирующая последовательность, \xhh, совпадает с двухбайтным UTF-8 символом, если его значение превышает 127.

После "\0" считываются две восьмеричные цифры. Если в записи менее двух цифр, будут использованы все фактически присутствующие цифры. Таким образом, последовательность "\0\x\07" будет интерпретирована как два бинарных нуля, за которыми следует символ оповещения (звонок). В случае, если вы используете представление числа в восьмеричном коде, убедитесь, что за начальным нулем следуют две значащие цифры.

Обработка обратного слеша, за которым следует ненулевая цифра, несколько сложнее. Вне символьного класса PCRE воспринимает обратный слеш и следующие за ним цифры как десятичное число. Если полученное значение меньше десяти, либо если шаблон содержит по меньшей мере такое же количество предшествующих текущей позиции подмасок, вся конструкция интерпретируется как ссылка на подмаску. Более детальное описание будет приведено ниже при обсуждении механизма работы подмасок.

Внутри символьного класса, либо если полученное значение больше 9 и соответствующее количество предшествующих подмасок отсутствует, PCRE считывает до трех восьмеричных цифр, следующих за обратным слешем, и генерирует один байт из последних 8-ми значащих битов полученного значения. Все последующие цифры обозначают себя же. Например:

\040
еще один способ записи пробела
\40
то же самое в случае, если данной записи предшествует менее сорока подмасок
\7
всегда интерпретируется как ссылка на подмаску
\11
может быть как обратной ссылкой, так и альтернативной записью символа табуляции
\011
всегда интерпретируется как символ табуляции
\0113
символ табуляции, за которым следует цифра "3"
\113
интерпретируется как символ с восьмеричным кодом 113 (так как ссылок на подмаски не может быть более чем 99)
\377
байт, всецело состоящий из единичных битов
\81
либо обратная ссылка, либо бинарный ноль, за которым следуют цифры "8" и "1"

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

Все последовательности, определяющие однобайтное значение, могут встречаться как внутри, так и вне символьных классов. Кроме того, внутри символьного класса запись "\b" интерпретируется как символ возврата ('backspace', шестнадцатеричный код 08). Вне символьного класса она имеет другое значение (какое именно, описано ниже).

Третье использование обратного слеша - указание общего типа символов:

\d
любая десятичная цифра
\D
любой символ, кроме десятичной цифры
\h
любой горизонтальный пробельный символ (начиная с версии PHP 5.2.4)
\H
любой символ, не являющийся горизонтальным пробельным символом (начиная с версии PHP 5.2.4)
\s
любой пробельный символ
\S
любой непробельный символ
\v
любой вертикальный пробельный символ (начиная с версии PHP 5.2.4)
\V
любой символ, не являющийся вертикальным пробельным символом (начиная с версии PHP 5.2.4)
\w
Любой символ, образующий "слово"
\W
Любой символ, не образующий "слово"

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

Следующие символы считаются как "пробельные": HT (9), LF (10), FF (12), CR (13), и пробел (32). Тем не менее, если идет локале-зависимый поиск, и произойдет совпадение с символами в диапазоне 128-255, они также будут восприняты как пробельные, например NBSP (A0).

Символ, образующий "слово" - это произвольная цифра, буква или символ подчеркивания, проще говоря, любой символ, который может являться частью "слова" в Perl. Определение букв и цифр управляется символьными таблицами, с которыми была собрана PCRE. И, как следствие, эти наборы могут отличаться в различных локализированных дистрибутивах. Например, в локали "fr" (Франция) некоторые символы с кодом выше 128 используются для записи ударных символов и, соответственно, соответствуют маске \w.

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

Четвертое использование обратного слеша - определение некоторых формальных утверждений, описывающих условия касательно месторасположения особых позиций в строке и совершенно не затрагивающих сами символы. Использование подмасок как более сложных формальных утверждений описано ниже. Такими управляющими последовательностями являются:

\b
граница слова
\B
не является границей слова
\A
начало данных (независимо от многострочного режима)
\Z
конец данных либо позиция перед последним переводом строки (независимо от многострочного режима)
\z
конец данных (независимо от многострочного режима)
\G
первая совпадающая позиция в строке

Описанные выше последовательности не могут встречаться в символьных классах (исключая комбинацию "\b", которая внутри класса означает символ возврата 'backspace').

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

Специальные последовательности \A, \Z и \z отличаются от общеупотребляемых метасимволов начала строки '^' и конца строки '$' (описанных в разделе якоря) тем, что они всегда совпадают либо в самом начале либо в самом конце строки. На них никак не влияют опции PCRE_MULTILINE и PCRE_DOLLAR_ENDONLY. Разница между \Z и \z в том, что \Z соответствует позиции перед последним символом в случае, если последний символ - перевод строки, кроме самого конца строки. В то время, как \z соответствует исключительно концу данных.

Утверждение \G является истинным только в том случае, если текущая проверяемая позиция находится в начале совпадения, указанного параметром offset функции preg_match(). Она отличается от \A при ненулевом значении параметра offset.

\Q и \E могут быть использованы для игнорирования метасимволов регулярных выражений в шаблоне. Например: \w+\Q.$.\E$ совпадет с один или более символов, составляющих "слово",за которыми следуют символы .$. и якорь в конце строки.

Последовательность \K может быть использована для сброса начала совпадения начиная с версии PHP 5.2.4. Например, шаблон foo\Kbar совпадет с "foobar", но сообщит о том, что совпал только с "bar". Использование \K не мешает установке подмасок. Например, если шаблон (foo)\Kbar совпадет со строкой "foobar", первой подмаской все равно будет являться "foo".

add a note add a note

User Contributed Notes 7 notes

up
55
mike at eastghost dot com
5 years ago
"line break" is ill-defined:

-- Windows uses CR+LF (\r\n)
-- Linux LF (\n)
-- OSX CR (\r)

Little-known special character:
\R in preg_* matches all three.

preg_match( '/^\R$/', "match\nany\\n\rline\r\nending\r" ); // match any line endings
up
4
grigor at the domain gatchev.info
6 years ago
As \v matches both single char line ends (CR, LF) and double char (CR+LF, LF+CR), it is not a fixed length atom (eg. is not allowed in lookbehind assertions).
up
-1
vea dot git at gmail dot com
4 months ago
\b BS

$str=""

$str =str_replace("\b", "", $str);
//echo 

$str =str_replace(chr(8), "", $str);
//echo

$str =str_replace("\\b", "", $str);
//echo
up
-9
bluemoehre at gmx dot de
3 years ago
Using \R in character classes is NOT possible:

var_dump( preg_match('#\R+#',"\n") ); -> int(1)
var_dump( preg_match('#[\R]+#',"\n") ); -> int(0)
up
-7
error17191 at gmail dot com
2 years ago
Some escape sequence like the tab character \t won't work inside single quotes '\t', But they work inside double quotes.
Other escape sequences like the backspace character won't work unless you use its ascii codepoint and chr() function i.e. chr(8)
up
-10
info at maisuma dot jp
3 years ago
You can use Unicode character escape sequences (tested on PHP 5.3.3 & PCRE 7.8).

<?php
//This source is supposed to be written in UTF-8.
$a='€';
var_dump(preg_match('/\\x{20ac}/u',$a)); //Match!
up
-23
collons at ya dot com
4 years ago
The pattern "/\\A/" may be replaced by "/\\\A/" in order to match a "\A" string. Any other escaped "\" looks to work fine so you can use "/\\S/", for instance, to match a "\S" string.
To Top