2012-04-30 10 views
8

Se pregunta si alguien por ahí puede arrojar alguna luz sobre por qué está fallando cuando se utiliza la siguiente expresión regular en función preg_match de PHP: -"preg_match(): Compilación falló: paréntesis incomparables" en PHP para el patrón válido

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

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

print_r($matches); 
?> 

Esto da como resultado el mensaje de error "preg_match(): Compilación fallida: paréntesis no coincidentes" a pesar de que el patrón parece ser válido. Lo probé con un PHP Regular Expression tester en línea y la herramienta de Linux Kiki. Parece que PHP está escapando del paréntesis de apertura en lugar de la barra invertida.

Ya solucioné el problema utilizando str_replace para cambiar las barras diagonales inversas por las reenviadas. Esto funciona para mi situación, pero sería bueno saber por qué esta expresión regular está fallando.

Respuesta

15

para codificar una barra invertida literal, tiene que escapar dos veces: una vez para la cadena, y una vez para el motor de expresiones regulares:

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

En PHP (cuando se utiliza una comilla), esto es sólo relevante para barras invertidas reales; otro escapa de expresiones regulares son bien con una sola barra invertida:

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

Esto se trata en the manual (véase el cuadro denominado "Nota:" en la parte superior de la página).

+1

Está encerrado entre comillas simples, ¿es realmente necesario para escapar dos veces? – Zombaya

+0

Bien hecho, me recuerda a algunos regexe locos que he usado en el pasado, p. 'sed/\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ ' – Petah

+0

@Zombaya: Sí, pero solo si se trata de una barra diagonal inversa real que está intentando codificar. –

0

extraña Acabo de prueba utilizando el mismo probador de expresiones regulares en línea que usted ha mencionado y se compilan sin errores:

<?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

Lo siento, probablemente no estaba claro en mi pregunta, pero la herramienta en línea lo acepta como válido, pero falla en mi código real (incluso cuando usa el código de salida de la herramienta). La expresión regular debería ser válida. – drmonkeyninja

1

usted tiene que utilizar |\\\tmp\\\([A-Za-z0-9]+)| expresión

pero hay una mejor manera de obtener el nombre de archivo porque de forma concreta de cuerda. por ejemplo:

substr($str, 5, -4); 

pensar en el uso de memoria

+0

El valor de my $ str fue solo un ejemplo. La mejor forma de obtener el valor del nombre del archivo en PHP sería usar la función pathinfo. – drmonkeyninja

0

Usar la siguiente expresión regular:

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 
) 
Cuestiones relacionadas