web-dev-qa-db-fra.com

Comment puis-je exploser et couper les espaces?

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 et les parcourir en boucle:

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

Mais j’ai le sentiment qu’il existe une approche d’une seule ligne capable de gérer cela. Des idées?

125
SeanWM

Vous pouvez faire ce qui suit en utilisant array_map :

$new_arr = array_map('trim', explode(',', $str));
358
SeanWM

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 sur virgule seulement
  • Découpe les espaces de chaque élément.
  • Ignore les éléments vides
  • Ne divise pas un élément avec des espaces internes comme "chose verte"
38
Amr ElAdawy

Les éléments suivants traitent également des espaces en début/fin de chaîne d'entrée:

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

et ceci est un test minimal avec des espaces blancs dans toutes les positions sensibles:

$str = ' first , second , third , fourth, fifth ';
$new_arr = preg_split('/\s*,\s*/', trim($str));
var_export($str);
19
Diego Perini

Vous pouvez aussi le faire avec une regex d'une ligne

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

En combinant certains des principes dans les réponses existantes, je suis venu avec

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 retournera 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 indiqué dans cette réponse pour le supprimer, mais une fois que vous le faites, il est techniquement pas besoin de supprimer les virgules consécutives via l'expression régulière, donc l'expression abrégée

2
shmurf

essaye ça:

$str = preg_replace("/\s*,\s*/", ",", 'red,     green,     blue ,orange');
1
Jason OOO

SPÉCIFIQUEMENT pour la chaîne exemple de l'OP, car chaque sous-chaîne à faire correspondre est un mot unique, 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

Sortie:

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

Cela peut également être adapté pour des sous-chaînes au-delà des lettres (et de certains traits d'union et apostrophes - si vous lisez les détails) en ajoutant les caractères nécessaires au masque de caractère/troisième paramètre.

Code: ( Démo )

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

Sortie:

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

Encore une fois, je traite cette question très étroitement à cause de l'exemple de chaîne, mais cela produira le même résultat souhaité:

Code: ( Démo )

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

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
  )
 */
0
Sutandiono