Comment puis-je exploser et découper les espaces?

167

Par exemple, je voudrais créer un tableau à partir des éléments de cette chaîne:

$str = 'red,     green,     blue ,orange';

Je sais que vous pouvez les exploser, les parcourir en boucle et les couper:

$arr = explode(',', $str);
foreach ($arr as $value) {
    $new_arr[] = trim($value);
}

Mais j'ai l'impression qu'il existe une approche en une seule ligne qui peut gérer cela. Des idées?

SeanWM
la source

Réponses:

449

Vous pouvez effectuer les opérations suivantes à l'aide de array_map :

$new_arr = array_map('trim', explode(',', $str));
SeanWM
la source
10
Ceci est également en boucle (en interne) par PHP
Jason OOO
2
ceci .... sauvé .... ma ... vie .... J'essayais de manipuler un fichier via fseek pour l'ajouter à la fin d'un fichier ... une fois que j'ai décidé de le diviser en un tableau et de le réécrire le fichier, j'ai vu qu'il y avait des espaces supplémentaires ajoutés tout le temps ... cela + imploser m'a sauvé la vie ... Je peux aller manger de la nourriture maintenant.
jenki221
4
@JasonOOO Je pense que de l'avis de la plupart des gens, quelques millisecondes (voire cela) est un compromis équitable pour avoir une ligne de code courte, simple et facilement lisible.
Gavin le
Simple et facile à comprendre. Cependant, s'il s'agit d'ensembles de données volumineux, la réponse la plus performante fournie par @ amr-eladwy est la meilleure solution.
Yaron
J'adore ce morceau de code et reviens sur ce site de temps en temps!
patrickzzz
52

Une réponse améliorée

preg_split ('/(\s*,*\s*)*,+(\s*,*\s*)*/', 'red,     green thing ,,  ,,   blue ,orange');

Résultat:

Array
(
    [0] => red
    [1] => green thing
    [2] => blue
    [3] => orange
)

Ce

  • Divise uniquement par des virgules
  • Réduit les espaces blancs de chaque élément.
  • Ignore les éléments vides
  • Ne divise pas un élément avec des espaces internes comme "chose verte"
Amr ElAdawy
la source
7
Quelqu'un peut-il m'expliquer pourquoi cette réponse n'a pas 100 votes positifs? L'expression régulière est difficile à comprendre, mais elle a analysé mon fichier de 100 Mo plus rapidement que les autres solutions
Dan
2
Je suis heureux que vous l'ayez trouvé utile. J'ai lu toutes les réponses et suis venu avec un meilleur mélange. Le regex peut être expliqué en détails.
Amr ElAdawy
2
Désolé mais cette expression régulière est erronée - essayez de la remplacer redpar *red*. Un meilleur pourrait être / (\ s *, \ s *) + /
Greg
@AmrElAdawy FYI cela ne fonctionne plus après la mise à jour 8/28. Avec l'expression régulière dans la réponse telle quelle, les espaces blancs ne sont pas supprimés de certains éléments. Ex: «chose verte».
Samsquanch
1
@Samsquanch mis à jour. S'il vous plaît laissez-moi savoir si vous voyez un problème.
Amr ElAdawy
25

Ce qui suit prend également en charge les espaces blancs au début / à la fin de la chaîne d'entrée:

$new_arr = preg_split('/\s*,\s*/', trim($str));

et ceci est un test minimal avec des espaces blancs dans chaque position sensible:

$str = ' first , second , third , fourth, fifth ';
$new_arr = preg_split('/\s*,\s*/', trim($str));
var_export($str);
Diego Perini
la source
Puisque les array_mapsolutions et regexp produisent des résultats identiques, quelqu'un pourrait-il comparer leurs performances?
Dan
@Dan Pour des cas comme celui-ci, il n'y aura aucune différence.
Aris
4

voici comment remplacer et exploser en une seule ligne de code

$str = 'red,     green,     blue ,orange';

$new_string = explode(',',preg_replace('/\s+/', '', $str));

affichera les résultats comme

Array
(
    [0] => red
    [1] => green
    [2] => blue
    [3] => orange
)
Amit Sharma
la source
3

En combinant certains des principes dans les réponses existantes, j'ai trouvé

preg_split ('/\s*,+\s*/', 'red,     green thing ,,  ,,   blue ,orange', NULL, PREG_SPLIT_NO_EMPTY);

Le raisonnement derrière cela est que j'ai trouvé un bogue dans cette réponse , où s'il y a une virgule à la fin de la chaîne, elle renverra un élément vide dans le tableau. c'est à dire

preg_split ('/(\s*,*\s*)*,+(\s*,*\s*)*/', 'red,     green thing ,,  ,,   blue ,orange,');

Résulte en

Array
(
  [0] => red
  [1] => green thing
  [2] => blue
  [3] => orange
  [4] => ''
)

Vous pouvez résoudre ce problème en utilisant PREG_SPLIT_NO_EMPTY comme mentionné dans cette réponse pour le supprimer, mais une fois que vous faites cela, il n'est techniquement pas nécessaire de supprimer des virgules consécutives via l'expression régulière, donc l'expression raccourcie

shmurf
la source
2

Vous pouvez également le faire avec une expression régulière d'une ligne

preg_split('@(?:\s*,\s*|^\s*|\s*$)@', $str, NULL, PREG_SPLIT_NO_EMPTY);
Dom
la source
1

essaye ça:

$str = preg_replace("/\s*,\s*/", ",", 'red,     green,     blue ,orange');
Jason OOO
la source
L'OP veut un tableau. preg_replace()ne génère pas de tableau à partir d'une chaîne. C'est la bonne réponse à la mauvaise question. Voté contre.
mickmackusa
1
$list = preg_split("/\s*,\s*/", 'red, green, blue ,orange');modification mineure réhabilite la réponse
dreftymac
1

SPÉCIFIQUEMENT pour la chaîne d'exemple de l'OP, car chaque sous-chaîne à mettre en correspondance est un seul mot, vous pouvez utiliser str_word_count () .

Code: ( Démo )

$str = ' red,     green,     blue ,orange ';
var_export(str_word_count($str,1));  // 1 means return all words in an indexed array

Production:

array (
  0 => 'red',
  1 => 'green',
  2 => 'blue',
  3 => 'orange',
)

Cela peut également être adapté pour les sous-chaînes au-delà des lettres (et certains tirets et apostrophes - si vous lisez les petits caractères) en ajoutant les caractères nécessaires au masque de caractère / 3e paramètre.

Code: ( Démo )

$str = " , Number1 ,     234,     0 ,4heaven's-sake  ,  ";
var_export(str_word_count($str,1,'0..9'));

Production:

array (
  0 => 'Number1',
  1 => '234',
  2 => '0',
  3 => '4heaven\'s-sake',
)

Encore une fois, je traite cette question très étroitement en raison de la chaîne d'exemple, mais cela fournira le même résultat souhaité:

Code: ( Démo )

$str = ' red,     green,     blue ,orange ';
var_export(preg_match_all('/[^, ]+/',$str,$out)?$out[0]:'fail');
Mickmackusa
la source
0

Vous pouvez utiliser preg_split () pour cela.

$bar = preg_split ('/[,\s]+/', $str);
print_r ($bar);

/* Result:
  Array
  (
      [0] => red
      [1] => green
      [2] => blue
      [3] => orange
  )
 */
Sutandiono
la source
Cela se divisera en espaces dans vos éléments
Chris KL
Déplacez la virgule à gauche des accolades pour rendre la virgule obligatoire.
Eric Leschinski
Déplacer la virgule vers la gauche ne résoudra pas cela. Veuillez vérifier ma réponse ci-dessous stackoverflow.com/a/38300330/5079380
Amr ElAdawy
-4
$str = str_replace(" ","", $str);
Noir blanc
la source
4
Trim fait plus que ça ... Il trims \t\n\r\0\x0Baussi
Arian Faurtosh
3
Non seulement cela, mais cela va bousiller les éléments avec de l'espace.
Adam Kiss
-11

couper et exploser

$ str = 'rouge, vert, bleu, orange';

$ str = trim ($ str);

$ strArray = exploser (',', $ str);

print_r ($ strArray);

Anil M Saini
la source
5
Cela supprime uniquement les espaces du début et de la fin d'une chaîne, pas entre chaque couleur.
SeanWM