2010-01-20 18 views
5

Estoy usando php's preg_split para dividir una cadena basada en punto y coma, pero necesito que solo se divida en punto y coma no escapado.Regex para spliting en todos los puntos y comas

<? 
$str = "abc;def\\;abc;def"; 
$arr = preg_split("/;/", $str); 
print_r($arr); 
?> 

Produce:

Array 
(
    [0] => abc 
    [1] => def\ 
    [2] => abc 
    [3] => def 
) 

Cuando quiero que produzca:

Array 
(
    [0] => abc 
    [1] => def\;abc 
    [2] => def 
) 

He intentado "/(^\\)?;/" o "/[^\\]?;/" pero ambos producen errores. ¿Algunas ideas?

+1

@Corey, ¿por qué se escapó el punto y coma si no lo quieres en tu producción final? –

+0

@Doug Typo, agregado semi-puntos en la salida final –

+0

¿Se pueden escapar los escapes? En otras palabras, ¿puede una cadena literal tener el siguiente aspecto: '" abc; def \\\\; abc; def "' (dividido en: '[abc, def \\, abc, def'])? –

Respuesta

5

Esto funciona.

<? 
    $str = "abc;def\;abc;def"; 
    $arr = preg_split('/(?<!\\\);/', $str); 
    print_r($arr); 
?> 

Genera:

Array 
(
    [0] => abc 
    [1] => def\;abc 
    [2] => def 
) 

Necesitas hacer uso de una búsqueda hacia atrás negativo (read about lookarounds). Piense en "combinar todo"; a menos que esté precedido por un '\' ".

+0

¡Gracias por el enlace! –

+0

Eso funcionará a menos que tenga un elemento que finalice con una barra diagonal inversa: no hay forma de escapar de esa barra diagonal inversa, ya que para la expresión regular parece que se está escapando del punto y coma. – Ariel

2

No estoy realmente hábil con expresiones regulares de PHP, pero trata de éste:

/(?<!\\);/ 
+0

Tiene que ser un triple '\'. Usando solo 2 errores producidos aquí. No estoy seguro de por qué esto es así. –

+0

Tu respuesta funciona con el triple '\', pero Nils dio un paso más para explicar por qué. ¡Sin embargo, obtenga un +1 por esfuerzo! –

0

Dado que Bart pregunta: Por supuesto, también puede usar regex para dividir en sin protección; y tener en cuenta los personajes de escape escapados. Simplemente se pone un poco desordenado:

<? 
    $str = "abc;def\;abc\\\\;def"; 
    preg_match_all('/((?:[^\\\\;]|\\\.)*)(?:;|$)/', $str, $arr); 
    print_r($arr); 
?> 

Array 
(
    [0] => Array 
     (
      [0] => abc; 
      [1] => def\;abc\\; 
      [2] => def 
    ) 

    [1] => Array 
     (
      [0] => abc 
      [1] => def\;abc\\ 
      [2] => def 
    ) 
) 

Lo que esto hace es tomar una expresión regular para “(cualquier carácter excepto \ y;) o (\ seguido de cualquier carácter)” y permitir que cualquier número de ellos, seguido por a; o el final de la cadena.

No estoy seguro de cómo php maneja los caracteres $ y de fin de línea dentro de una cadena, puede que necesite establecer algunas opciones de expresiones regulares para obtener exactamente lo que desea para esas.

Cuestiones relacionadas