Les chaînes entre quotes simples ou doubles (première couche):
À la base un antislash se représente par lui-même comme n'importe quel caractère:
1 2
| echo 'a\b'; # a\b
echo "a\b"; # a\b |
Mais l'antislash n'est pas un caractère comme les autres car c'est précisément lui qui est utilisé pour l'échappement dans les chaînes simple quote, double quote et heredoc.
L'échappement d'un caractère consiste à signifier, en plaçant un antislash avant lui, que le dit caractère n'est pas à prendre dans son sens habituel. Exemples:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| echo '\''; # échappement du 2nd quote pour signifier qu'il ne marque pas la fin de chaîne
# '
echo '\\'; # là on signifie que le deuxième antislash n'est pas un caractère d'échappement (afin qu'il n'échappe pas le quote de fin de chaîne)
# \
echo 'a\tb'; # les séquences d'échappements ne sont pas interprétées entre simple quotes
# a\tb
echo "a\tb"; # il ne s'agit pas d'un antislash puis d'un "t" mais de la séquence "\t" représentant une tabulation
# a b
echo "a\\tb"; # si je veux afficher un antislash et un "t", j'échappe l'antislash comme précédemment
# a\tb |
Il en découle qu'un antislash peut être représenté de deux manières:
- soit par un seul antislash si le caractère suivant ne voit pas sa signification modifiée par sa présence, comme c'est le cas pour a\b.
- soit par deux antislashes.
Donc si je veux représenter la chaîne
l\'AB entre double quotes, je peux l'écrire indifféremment:
"l\'AB" ou
"l\\'AB". Par contre si je veux représenter cette même chaîne entre simple quotes je ne peux écrire que
'l\\\'AB' avec les deux premiers antislashes qui figure l'antislash littéral, et le troisième qui échappe le simple quote pour éviter que la chaîne ne se termine. Je ne peux pas écrire
'l\'AB' car l'antislash servant à échapper le quote ne sera pas affiché, et encore moins
'l\\'AB' car la chaîne s'arrêterait prématurément.
À noter que dans une chaîne nowdoc, comme aucune séquence d'échappement n'est interprétée et qu'il n'y aucune limite de chaîne à échapper, l'antislash se représente toujours par un seul antislash, ce qui peut s'avérer utile pour simplifier l'écriture.
La pattern regex (deuxième couche):
Là où ça se complique c'est que l'antislash sert également de caractère d'échappement dans les patterns regex (pour échapper les caractères spéciaux
( ) [ { . ? + * | ^ $ \ parmi lesquels il figure d'ailleurs, pour les classes de caractères
\w \W \d \D \s \S \p{truc} \P{bidule}, pour les ancres
\A \z \b \B, l'alias
\R, les références aux groupes, aux captures...)
C'est pourquoi il faut tout ré-échapper une deuxième fois! Il faut donc transmettre non plus la chaîne
l\'AB mais la chaîne
l\\'AB.
À la limite, pour ne pas se casser la tête, on pourrait utiliser
preg_quote qui le fera tous seul comme un grand pour les parties littérales de la chaîne:
1 2 3 4
| $pattern = "#" . preg_quote(" l\'AB ", "#") . "#";
// ou $pattern = "#" . preg_quote(" l\\'AB ", "#") . "#";
// ou $pattern = "#" . preg_quote(' l\\\'AB ', "#") . "#";
echo $pattern; // # l\\'AB # |
ou encore utiliser la syntaxe nowdoc:
1 2 3
| $pattern = <<<'EOF'
# l\\'AB #
EOF; |
Pour ce qui est des chaînes entre quotes la difficulté est alors d'avoir à représenter deux antislashes consécutifs. Donc d'après ce qu'on a vu précédemment, on peut le faire avec trois antislashes (les deux premiers figureront le premier antislash littérale et le dernier le second) ou quatre antislashes (deux pour chaque antislash littérale). Ainsi on peut écrire:
1 2 3
| $pattern = "# l\\\'AB #";
// ou bien
$pattern = "# l\\\\'AB #"; |
Si je veux l'écrire entre simple quotes, s'ajoute la contrainte du simple quote qu'il faut échapper qui me force à utiliser deux antislashes pour chaque antislash littéral afin que le 5e antislash échappe le simple quote:
$pattern = '# l\\\\\'AB #';
Partager