PHP Australia Conference 2015

Séquences d'échappement

Le caractère antislash a de nombreuses utilisations. En premier lieu, s'il est suivi d'un caractère non alphanumérique, il ne prendra pas la signification spéciale qui y est rattachée. Cette utilisation de l'antislash comme caractère de protection s'applique à l'intérieur et à l'extérieur des classes de caractères.

Par exemple, pour rechercher le caractère étoile "*", il faut écrire dans le masque : "\*". Cela s'applique dans tous les cas, que le caractère qui suive soit un métacaractère ou non. C'est un moyen sûr pour s'assurer qu'un caractère sera recherché pour sa valeur littérale, plutôt que pour sa valeur spéciale. En particulier, pour rechercher les antislashs, il faut écrire : "\\".

Note:

La chaîne de caractères PHP simple ou double guillemet a une signification spéciale des antislashs. Donc, si \ doit être recherché avec une expression rationnelle \\, alors "\\\\" ou '\\\\' doit être utilisé dans le code PHP.

Si un masque est utilisé avec l'option PCRE_EXTENDED, les espaces blancs du masque, mais qui ne sont pas dans une classe de caractères, et les caractères entre dièse "#", ainsi que les nouvelles lignes sont ignorées. L'antislash peut être utilisé pour les protéger et ainsi rechercher un espace ou un dièse.

La deuxième utilité de l'antislash est de pouvoir coder des caractères invisibles dans les masques. Il n'y a pas de restriction sur la place de ces caractères invisibles, hormis pour le caractère nul qui doit terminer le masque. Lors de la préparation du masque, il est souvent plus pratique d'utiliser les séquences d'échappement suivantes, plutôt que le caractère binaire qu'elles représentent :

\a
alarme, c'est-à-dire le caractère BEL (hex 07)
\cx
"contrôle-x", avec x qui peut être n'importe quel caractère.
\e
escape (hex 1B)
\f
formfeed (hex 0C)
\n
nouvelle ligne (hex 0A)
\p{xx}
un caractère avec une propriété xx, voir les propriétés unicode pour plus d'informations
\P{xx}
un caracère sans propriété xx, voir les propriétés unicode pour plus d'informations
\r
retour chariot (hex 0D)
\t
tabulation (hex 09)
\xhh
caractère en hexadécimal, de code hh
\ddd
caractère en octal, de code ddd, ou référence arrière

Dans la séquence "\cx" si "x" est en minuscule, il est converti en majuscule. Puis, le bit 6 (hex 40) est inversé. Ainsi "\cz" devient 1A, mais "\c{" devient hex 3B, tandis que "\c;" devient hex 7B.

Après "\x", deux caractères hexadécimaux sont lus (les lettres peuvent être en majuscule ou minuscule). En mode UTF-8, "\x{...}" est autorisée, où le contenu des accolades est une chaîne hexadécimale. Il sera interprété comme un caractère UTF-8 où le numéro de code est le numéro hexadécimal donné. La séquence d'échappement hexadécimale originale, \xhh, correspond à un caractère UTF-8 sur 2 octets si la valeur est plus grande que 127.

Après "\0", deux caractères octaux sont lus. Dans chacun des cas, le métacaractère tente de lire autant de caractères que possible. Ainsi, la séquence "\0\x\07" sera comprise comme deux caractères nuls, suivis d'un caractère alarme (BEL). Assurez-vous que vous fournissez suffisamment de chiffres après le métacaractère.

L'antislash de fin suivi par un nombre autre que 0 est compliqué. À l'extérieur d'une classe de caractère, PCRE le lit, et tous les nombres qui suivent, en tant que nombres décimaux. Si le nombre est plus petit que 10 ou s'il y a eu au moins précédemment une parenthèse gauche capturante dans l'expression, la séquence entière est prise en tant que référence arrière. Une description sur le fonctionnement est donnée plus tard, suivez la discussion sur les parenthèses des sous masques.

À l'intérieur d'un caractère de classe ou s'il est plus grand que 9, et qu'il n'y a pas eu assez de parenthèses ouvrantes auparavant, PCRE lit jusqu'à 3 chiffres octaux à la suite de l'antislash, et génère un octet unique, à partir des 8 bits de poids faible de la séquence. Tous les chiffres qui suivent ne sont pas interprétés, et se représentent eux-mêmes. Par exemple:

\040
une autre manière d'écrire un espace
\40
identique, dans la mesure où il n'y a pas 40 parenthèses ouvrantes auparavant
\7
est toujours une référence arrière
\11
peut être une référence de retour, ou une tabulation
\011
toujours une tabulation
\0113
est une tabulation suivie du caractère "3"
\113
est le caractère 113 (étant donné qu'il ne peut y avoir plus de 99 références arrières)
\377
est un octet dont tous les bits sont à 1
\81
peut être soit une référence arrière, soit un zéro binaire suivi des caractères "8" et "1"

Les valeurs octales supérieures ou égales à 100 ne doivent pas être introduites par un 0, car seuls les trois premiers octets seront lus.

Toutes les séquences qui définissent une valeur d'un seul octet peuvent être utilisées dans les classes de caractères, et à l'extérieur. De plus, dans une classe de caractères, la séquence "\b" est interprétée comme un caractère effacer (hex 08). À l'extérieur, elle peut avoir d'autres significations (voir ci-dessous).

On peut encore se servir de l'antislash pour préciser des types génériques de valeurs :

\d
tout caractère décimal
\D
tout caractère qui n'est pas un caractère décimal
\h
n'importe quel espace horizontal (depuis PHP 5.2.4)
\H
n'importe quel caractère qui n'est pas un espace horizontal (depuis PHP 5.2.4)
\s
tout caractère blanc
\S
tout caractère qui n'est pas un caractère blanc
\v
n'importe quel espace vertical (depuis PHP 5.2.4)
\V
n'importe quel caractère qui n'est pas un espace vertical (depuis PHP 5.2.4)
\w
tout caractère de "mot"
\W
tout caractère qui n'est pas un caractère de "mot"

Chaque paire précédente définit une partition de la table des caractères : les deux ensembles sont disjoints. Un caractère satisfera soit un métacaractère, soit l'autre.

Un caractère de "mot" sera une lettre, un chiffre ou le caractère souligné, c'est-à-dire un caractère qui pourra être une partie d'un mot Perl. La définition des lettres et chiffres est définie par les tables de caractères de PCRE, et peut varier suivant la table locale de caractères. Par exemple, dans la configuration "français" ("fr"), certains caractères ont des codes supérieurs à 128, pour les caractères accentués, et ils seront compris par le métacaractère \w.

Ces séquences de caractères peuvent apparaître à l'intérieur ou à l'extérieur des classes de caractères. Elles remplacent à chaque fois un caractère du type correspondant. Si cette séquence est placée en fin de masque, et qu'il n'y a plus de caractère à comparer dans la chaîne sujet, la recherche échoue.

La quatrième utilisation de l'antislash intervient lors d'assertions simples. Une assertion impose une condition à un certain point, sans remplacer de caractère. L'utilisation de sous-masques pour réaliser des assertions plus complexes est décrite plus bas. Les assertions avec antislash sont les suivantes :

\b
limite de mot
\B
pas limite de mot
\A
début de la chaîne sujet (indépendant du mode multilignes)
\Z
fin de la chaîne sujet ou nouvelle ligne à la fin de la chaîne sujet (indépendant du mode multilignes)
\G
position de la première occurrence trouvé dans la chaîne sujet
\z
fin de la chaîne sujet (indépendant du mode multilignes)

Ces assertions ne peuvent pas apparaître dans une classe de caractères (mais "\b" a une autre signification à l'intérieur d'une classe de caractères).

Une limite de mot est un emplacement dans la chaîne sujet ou un caractère et son suivant ne sont pas en même temps des caractères de mot (\w), ou le contraire (\W) (on peut le voir comme \w\W ou \W\w), ou encore le premier ou le dernier caractère est un caractère mot (\w).

Les assertions \A, \Z, et \z diffèrent des métacaractères ^ et $ dans la mesure où ils ne sont pas dépendants des options, notamment PCRE_MULTILINE ou PCRE_DOLLAR_ENDONLY. La différence entre \Z et \z tient au fait que \Z recherche les positions avant les nouvelles lignes et à la fin de la chaîne sujet, tandis que \z ne recherche que la fin de la chaîne.

L'assertion \G est réalisée uniquement lorsque la position courante de l'occurrence trouvée est au début de l'occurrence, comme spécifié par l'argument offset de la fonction preg_match(). Elle diffère de \A lorsque la valeur du paramètre offset est différente de zéro.

\Q et \E peuvent être utilisés pour ignorer les métacaractères dans le masque. Par exemple : \w+\Q.$.\E$ recherchera un ou plusieurs caractères suivis par la chaîne littérale .$. et ancrés à la fin de la chaîne.

\K peut être utilisé pour réinitialiser le résultat, depuis PHP 5.2.4. Par exemple, le masque foo\Kbar trouve "foobar", mais reporte q'il a trouvé "bar". L'utilisation de \K n'interfère pas avec la configuration des sous-chaînes capturantes. Par exemple, lorsque le masque (foo)\Kbar trouve "foobar", la première sous-chaîne sera toujours "foo".

add a note add a note

User Contributed Notes 6 notes

up
23
mike at eastghost dot com
2 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
6
grigor at the domain gatchev.info
3 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
4
info at silisoftware dot com
1 year ago
Whitespace matched by \s means only these 5 characters:
9 = 0x09 = horizontal tab
10 = 0x0A = line feed
12 = 0x0C = form feed
13 = 0x0D = carriage return
32 = 0x20 = space
up
0
info at maisuma dot jp
3 months 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
-1
collons at ya dot com
11 months 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.
up
-5
bluemoehre at gmx dot de
8 months 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)
To Top