2010-07-16 3 views
8

Est-ce que quelqu'un connaît une fonction explode() semblable et rapide qui peut ignorer les caractères séparateurs qui sont inclus dans une paire de caractères arbitraires (par exemple des guillemets)?Une fonction explode() qui ignore les caractères entre guillemets?

Exemple:

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

devrait aboutir à un tableau avec les membres suivants:

This is 
a string 
that should be 
exploded. 

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

le fait que les personnages sont enveloppés dans des guillemets simples leur épargnerait de splitters être.

points bonus pour une solution qui peut traiter deux caractères wrapper

(not/here) 

serait préféré une solution PHP native, mais je ne pense pas qu'une telle chose existe!

+0

duplication possible de [PHP exploser la chaîne, mais traiter les mots entre guillemets comme un seul mot] (http://stackoverflow.com/questions/2202435/php-explode-the-string-but-treat-words -in-quotes-as-a-single-word) – Bergi

Répondre

6

str_getcsv($str, '/')

Il y a une recette pour < 5.3 sur la page liée.

+0

+1, était sur le point de poster la même chose. –

+1

ne fonctionne pas pour moi. ne reconnaît pas le '' 'comme boîtier. – Gordon

+0

Alors, passez un caractère différent en tant que pièce jointe. –

0

Quelque chose de très proche avec preg_split: http://fr2.php.net/manual/en/function.preg-split.php#92632

Il gère plusieurs caractères wrapper et de multiples caractères délimiteurs.

+0

Cheers @ greg0ire, cela semble bon, mais a encore besoin d'un peu de travail. Je vais essayer de le changer à mes besoins avec ma faible connaissance de Regex. –

4

Ceci est presque impossible avec preg_split, car vous ne pouvez pas dire à partir du milieu de la chaîne si vous êtes entre guillemets ou non. Cependant, preg_match_all peut faire le travail.

solution simple pour un seul type de citation:

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

Cette fonction aura toutes sortes de problèmes si vous le transmettre certains caractères spéciaux (\^-], selon http://www.regular-expressions.info/reference.html), de sorte que vous aurez besoin d'échapper à ceux-ci. Voici une solution générale qui échappe à des caractères spéciaux regex et peut suivre plusieurs types de citations séparément:

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]; 
} 

(Notez que je garde toutes les variables entre crochets pour minimiser ce qui a besoin d'échapper - en dehors des crochets, il y a Si vous vouliez utiliser] comme une citation, alors vous vouliez probablement utiliser [comme la citation correspondante, mais je vais laisser ajouter cette fonctionnalité comme un exercice pour le lecteur. :)

+0

Cas de bordure: Si les guillemets ne sont pas équilibrés, cette fonction supprimera suffisamment d'entre eux pour les rendre équilibrés. – Brilliand

+0

Je viens de découvrir la fonction 'preg_quote' - c'est probablement une meilleure façon d'échapper des caractères dans les expressions régulières. – Brilliand

Questions connexes