52 votes

Scinde une chaîne par un délimiteur, mais pas si elle est échappé

Comment puis-je diviser une chaîne de caractères par un délimiteur, mais pas s'il s'est échappé? Par exemple, j'ai une chaîne de caractères:

1|2\|2|3\\|4\\\|4

Le délimiteur est - | et une échappé à délimiteur est - \|. En outre, je veux ignorer échappé barres obliques inverses, donc, en \\| le | serait encore un délimiteur.

Donc, avec les cordes le résultat devrait être:

[0] => 1
[1] => 2\|2
[2] => 3\\
[3] => 4\\\|4

107voto

NikiC Points 47270

L'utilisation de la magie noire:

$array = preg_split('~\\\\.(*SKIP)(*FAIL)|\|~s', $string);

\\\\. correspond à un antislash suivi d'un caractère, (*SKIP)(*FAIL) l'ignore et \| correspond à votre délimiteur.

11voto

Bart Kiers Points 79069

Au lieu de split(...), c'est de l'OMI, plus intuitif à utiliser une sorte de "scan" de la fonction qui fonctionne comme un lexicale générateur de jetons. En PHP qui serait l' preg_match_all fonction. Il vous suffit de dire que vous voulez faire correspondre:

  1. autre chose qu'un \ ou |
  2. ou un \ suivie par un \ ou |
  3. répétez #1 ou #2, au moins une fois

La démonstration suivante:

$input = "1|2\\|2|3\\\\|4\\\\\\|4";
echo $input . "\n\n";
preg_match_all('/(?:\\\\.|[^\\\\|])+/', $input, $parts);
print_r($parts[0]);

affichera:

1|2\|2|3\\|4\\\|4

Array
(
    [0] => 1
    [1] => 2\|2
    [2] => 3\\
    [3] => 4\\\|4
)

4voto

Anton Points 417

Récemment, j'ai mis au point une solution:

$array = preg_split('~ ((?<!\\\\)|(?<=[^\\\\](\\\\\\\\)+)) \| ~x', $string);

Mais la magie noire de la solution est encore trois fois plus vite.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X