2010-07-16 9 views
8

¿Alguien conoce una función similar explode() rápida y fácil que puede ignorar los caracteres del divisor que están encerrados en un par de caracteres arbitrarios (por ejemplo, comillas)?¿Una función de explosión() que ignora los caracteres dentro de las comillas?

Ejemplo:

my_explode(
    "/", 
    "This is/a string/that should be/exploded.//But 'not/here',/and 'not/here'" 
); 

debería resultar en una matriz con los siguientes miembros:

This is 
a string 
that should be 
exploded. 

But 'not/here', 
and 'not/here' 

el hecho de que los caracteres están envueltos en comillas simples sería evitarles de ser divisores.

puntos de bonificación para una solución que pueda hacer frente a dos personajes envoltura

(not/here) 

sería preferible una solución nativa de PHP, pero no creo que exista tal cosa!

+0

posible duplicado de [PHP explota la cadena, pero trata las palabras entre comillas como una sola palabra] (http://stackoverflow.com/questions/2202435/php-explode-the-string-but-treat-words -in-quotes-as-a-single-word) – Bergi

Respuesta

6

str_getcsv($str, '/')

Hay una receta para < 5.3 en la página enlazada.

+0

+1, estaba a punto de publicar lo mismo. –

+1

no funciona para mí. no reconoce el '' 'como recinto. – Gordon

+0

Entonces pase un carácter diferente como un recinto. –

0

Algo muy cerca con preg_split: http://fr2.php.net/manual/en/function.preg-split.php#92632

Maneja múltiples caracteres envoltura y múltiples caracteres delimitadores.

+0

Cheers @ greg0ire, esto se ve bien, pero aún necesita un poco de trabajo. Trataré de cambiarlo a mis necesidades con mi débil conocimiento de Regexes. –

4

Esto es casi imposible con preg_split, porque no se puede decir desde el medio de la cadena si está entre comillas o no. Sin embargo, preg_match_all puede hacer el trabajo.

solución simple para un solo tipo de cotización:

function quoted_explode($subject, $delimiter = ',', $quote = '\'') { 
    $regex = "(?:[^$delimiter$quote]|[$quote][^$quote]*[$quote])+"; 
    preg_match_all('/'.str_replace('/', '\\/', $regex).'/', $subject, $matches); 
    return $matches[0]; 
} 

Esa función tendrá todo tipo de problemas si se le pasa ciertos caracteres especiales (\^-], de acuerdo con http://www.regular-expressions.info/reference.html), por lo que necesito escapar de esos. Aquí hay una solución general que se escapa caracteres especiales de expresiones regulares y se puede realizar un seguimiento de varios tipos de cotizaciones por separado:

function regex_escape($subject) { 
    return str_replace(array('\\', '^', '-', ']'), array('\\\\', '\\^', '\\-', '\\]'), $subject); 
} 

function quoted_explode($subject, $delimiters = ',', $quotes = '\'') { 
    $clauses[] = '[^'.regex_escape($delimiters.$quotes).']'; 
    foreach(str_split($quotes) as $quote) { 
     $quote = regex_escape($quote); 
     $clauses[] = "[$quote][^$quote]*[$quote]"; 
    } 
    $regex = '(?:'.implode('|', $clauses).')+'; 
    preg_match_all('/'.str_replace('/', '\\/', $regex).'/', $subject, $matches); 
    return $matches[0]; 
} 

(Tenga en cuenta que guardo todas las variables entre corchetes para minimizar lo que necesita escapar - fuera de los corchetes, hay aproximadamente el doble de caracteres especiales.)

Si desea utilizar] como una cita, entonces probablemente desee utilizar [como la cita correspondiente, pero voy a dejar de agregar esa funcionalidad como un ejercicio para el lector. :)

+0

Edge Case: si las comillas no están balanceadas, esta función descartará una cantidad suficiente como para equilibrarlas. – Brilliand

+0

Acabo de enterarme de la función 'preg_quote'; esa es probablemente una mejor forma de escapar caracteres en expresiones regulares. – Brilliand

Cuestiones relacionadas