backslash extra necessaria in PHP modello regex
Domanda
Durante il test di risposta per domanda di un altro utente ho trovato qualcosa che non lo faccio capire. Il problema era quello di sostituire tutti i caratteri \t
\n
\r
letterali da una stringa con un singolo spazio.
Ora, il primo modello che ho provato era:
/(?:\\[trn])+/
che sorprendentemente non ha funzionato. Ho provato lo stesso schema in Perl e ha funzionato bene. Dopo alcuni tentativi ed errori ho scoperto che PHP vuole 3 o 4 barre rovesciate per quel modello per abbinare, come in:
/(?:\\\\[trn])+/
o
/(?:\\\[trn])+/
questi modelli - con mia grande sorpresa - sia il lavoro. Perché questi backslash aggiuntivi necessari?
Soluzione
È necessario 4 backslash per rappresentare 1 in regex perché:
- 2 backslash sono usati per unescaping in una stringa (
"\\\\" -> \\
) - 1 barra rovesciata viene utilizzata per unescaping nel motore regex (
\\ -> \
)
Dal doc PHP,
sfuggire qualsiasi altro carattere comporterà la barra rovesciata in fase di stampa troppo 1
Quindi, per \\\[
,
- 1 barra rovesciata viene utilizzata per la unescaping
\
, un soggiorno perché\[
è valido ("\\\[" -> \\[
) - 1 barra rovesciata viene utilizzata per unescaping nel motore regex (
\\[ -> \[
)
Si funziona, ma non è una buona pratica.
Altri suggerimenti
Le sue opere in Perl, perché si passa che direttamente come regex modello /(?:\\[trn])+/
, ma in PHP, è necessario passare come stringa, in modo da avere bisogno di ulteriore fuga per backslash sé.
"/(?:\\\\[trn])+/"
La regex \ per indicare un singolo backslash sarebbe diventato '/ \\\\ /' come PHP stringa preg
L'espressione regolare è solo /(?:\\[trn])+/
. Ma dal momento che è necessario per sfuggire alle backslash nelle dichiarazioni di stringa così, ogni backslash deve essere espresso con \\
:
"/(?:\\\\[trn])+/"
'/(?:\\\\[trn])+/'
A soli tre backspace funzionano anche perché PHP non conosce il \[
sequenza di fuga e lo ignora. Così \\
diventerà \
ma \[
rimarrà \[
.
Usa str_replace!
$code = str_replace(array("\t","\n","\r"),'',$code);
dovrebbe fare il trucco