2012-04-30 6 views
8

chiedo se qualcuno là fuori può far luce sul motivo per cui la seguente espressione regolare non riesce quando viene utilizzato nella funzione preg_match di PHP: -"preg_match(): Compilazione non riuscita: parentesi senza eguali" in PHP testo valido

<?php 
$str = '\tmp\phpDC1C.tmp'; 

preg_match('|\\tmp\\([A-Za-z0-9]+)|', $str, $matches); 

print_r($matches); 
?> 

Ciò risulta nel messaggio di errore "preg_match(): Compilazione non riuscita: parentesi non corrispondenti" nonostante il motivo sia valido. L'ho provato con uno strumento online PHP Regular Expression tester e lo strumento Linux Kiki. Sembra che PHP stia sfuggendo alla parentesi di apertura piuttosto che alla barra retroversa.

Ho risolto il problema utilizzando str_replace per scambiare i backslash per quelli in avanti. Questo funziona per la mia situazione, ma sarebbe bello sapere perché questa espressione regolare sta fallendo.

risposta

15

per codificare un backslash letterale, è necessario fuggire due volte: una volta per la stringa, e una volta per il motore regex:

preg_match('|\\\\tmp\\\\([A-Za-z0-9]+)|', $str, $matches); 

In PHP (quando si utilizza le stringhe racchiuse tra virgolette singole), questo è solo rilevante per i backslash effettivi; altre fughe regex sono OK con una singola barra rovesciata:

preg_match('/\bhello\b/', $subject) 

Questo è trattato nel the manual (vedi la casella "Nota:" nella parte superiore della pagina).

+1

E 'racchiuso tra virgolette singole, è davvero necessario per scappare due volte? – Zombaya

+0

Ben fatto, mi ricorda alcuni regex pazzi che ho usato in passato, ad es. 'sed/\\\\\\\\\\\\' o qualcosa del genere. – Petah

+0

@Zombaya: Sì, ma solo se si tratta di un vero backslash letterale che stai tentando di codificare. –

0

strano ho appena testato utilizzando lo stesso tester regex on-line che lei ha citato e compilati senza errori:

<?php 
$ptn = "/<;?php $str = '\tmp\phpDC1C.tmp'; 
preg_match('|\\tmp\\([A-Za-z0-9]+)|', $str, $matches); print_r($matches); ?>;/"; 
$str = ""; 
preg_match($ptn, $str, $matches); 
print_r($matches); 
?> 
+0

Mi spiace, probabilmente non è stato chiaro nella mia domanda, ma lo strumento online lo accetta come valido, ma non riesce nel mio codice reale (anche quando si utilizza l'output del codice dallo strumento). L'espressione regolare dovrebbe essere valida. – drmonkeyninja

1

è necessario utilizzare |\\\tmp\\\([A-Za-z0-9]+)| espressione

ma ci sono modo migliore per ottenere il nome del file, perché di forma concreta di corda. per esempio:

substr($str, 5, -4); 

pensare l'utilizzo della memoria

+0

Il valore del mio $ str era solo un esempio. Il modo migliore per ottenere il valore del nome file in PHP sarebbe utilizzare la funzione pathinfo. – drmonkeyninja

0

Usa il prossimo regex:

php >$str = '\tmp\phpDC1C.tmp'; 
php >preg_match('/[\\\\]tmp[\\\\]([A-Za-z0-9]+)/', $str, $matches); 
php >print_r($matches); 
Array 
(
    [0] => \tmp\phpDC1C 
    [1] => phpDC1C 
) 
Problemi correlati