217

For example, I would like to create an array from the elements in this string:

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

I know you can explode and loop through them and trim:

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

But I feel like there's a one line approach that can handle this. Any ideas?

mickmackusa
  • 43,625
  • 12
  • 83
  • 136
SeanWM
  • 16,789
  • 7
  • 51
  • 83

11 Answers11

572

You can do the following using array_map:

$new_arr = array_map('trim', explode(',', $str));
SeanWM
  • 16,789
  • 7
  • 51
  • 83
  • 12
    This is also looping (internally) by PHP – Jason OOO Oct 13 '13 at 15:47
  • 5
    @JasonOOO I think in most people's opinion, a couple milliseconds (if even that) is a fair tradeoff for having a line of code that is short, simple and easily readable. – Gavin Apr 05 '17 at 10:52
  • 2
    Simple and easy to understand. However, if dealing with large data sets, the more performant answer provided by @amr-eladwy is the better solution. – Yaron Mar 10 '18 at 23:13
73

An improved answer

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

Result:

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

This:

  • Splits on commas only
  • Trims white spaces from each item.
  • Ignores empty items
  • Does not split an item with internal spaces like "green thing"
Amr Eladawy
  • 4,193
  • 7
  • 34
  • 52
  • 8
    Can anyone explain me why this answer does not have 100 upvotes? Regexp is hard to understand, but it parsed my 100Mb file faster than other solutions – Dan Aug 18 '16 at 10:56
  • 2
    Sorry but this regex is wrong - try replacing `red` with `*red*`. A better one might be /(\s*,\s*)+/ – Greg Aug 09 '18 at 07:38
  • @AmrElAdawy FYI this no longer works after the 8/28 update. With the regex in the answer as-is, white space is not trimmed from some of the elements. Ex: ` green thing`. – Samsquanch Mar 27 '19 at 15:18
  • Hi @Samsquanch , can you help me more about that update? Do you have fiddler I can play around with? – Amr Eladawy Mar 27 '19 at 15:33
  • @AmrElAdawy here you go: https://www.phpliveregex.com/p/rrI#tab-preg-split – Samsquanch Mar 27 '19 at 15:39
  • 1
    @Samsquanch updated. Please let me know if you see any issue. – Amr Eladawy Mar 27 '19 at 15:50
  • 1
    Why your regexp not trim spaces around string? Example: ' red, green thing ,, ,, blue ,orange ' – wp-mario.ru Jul 22 '20 at 12:31
27

The following also takes care of white-spaces at start/end of the input string:

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

and this is a minimal test with white-spaces in every sensible position:

$str = ' first , second , third , fourth, fifth ';
$new_arr = preg_split('/\s*,\s*/', trim($str));
var_export($str);
Diego Perini
  • 8,003
  • 1
  • 18
  • 9
9

this how you replace and explode in a single line of code

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

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

will output the results as

Array
(
    [0] => red
    [1] => green
    [2] => blue
    [3] => orange
)
Amit Sharma
  • 1,775
  • 3
  • 11
  • 20
5

By combining some of the principals in the existing answers I came up with

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

The reasoning behind it is that I found a bug in this answer, where if there is a comma at the end of the string it'll return a blank element in the array. i.e.

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

Results in

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

You can fix this by using PREG_SPLIT_NO_EMPTY as mentioned in this answer to remove it, but once you are doing that there is technically no need to remove consecutive commas via the regex, thus the shortened expression

shmurf
  • 106
  • 1
  • 4
3

You can also do this with a one line regex

preg_split('@(?:\s*,\s*|^\s*|\s*$)@', $str, NULL, PREG_SPLIT_NO_EMPTY);
Dom
  • 2,980
  • 2
  • 28
  • 41
  • it creates multiple matches for spaces before and after in a string, for example " one, two, three " generates: Array ( [0] => [1] => one [2] => two [3] => three [4] => [5] => ) – Tamik Soziev Feb 28 '23 at 19:17
1

try this:

$str = preg_replace("/\s*,\s*/", ",", 'red,     green,     blue ,orange');
Jason OOO
  • 3,567
  • 2
  • 25
  • 31
  • The OP wants an array. `preg_replace()` doesn't generate an array from a string. This is the right answer to the wrong question. Downvoted. – mickmackusa Dec 02 '17 at 09:10
  • 1
    `$list = preg_split("/\s*,\s*/", 'red, green, blue ,orange');` minor modification rehabilitates the answer – dreftymac Aug 03 '18 at 23:03
1

SPECIFICALLY for the OP's sample string, because each substring to be matched is a single word, you can use str_word_count().

Code: (Demo)

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

Output:

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

This can also be adapted for substrings beyond letters (and some hyphens and apostrophes -- if you read the fine print) by adding the necessary characters to the character mask / 3rd parameter.

Code: (Demo)

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

Output:

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

Again, I am treating this question very narrowly because of the sample string, but this will provide the same desired output:

Code: (Demo)

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

Finally, if you want to split on commas with optional leading or trailing spaces, here is the call: (Demo)

var_export(
    preg_split ('/ *,+ */', $str, 0, PREG_SPLIT_NO_EMPTY)
);
mickmackusa
  • 43,625
  • 12
  • 83
  • 136
0

You can use preg_split() for that.

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

/* Result:
  Array
  (
      [0] => red
      [1] => green
      [2] => blue
      [3] => orange
  )
 */
Sutandiono
  • 1,748
  • 1
  • 12
  • 21
-4
$str = str_replace(" ","", $str);
SeanWM
  • 16,789
  • 7
  • 51
  • 83
BlackWhite
  • 814
  • 2
  • 12
  • 26
-12

trim and explode

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

$str = trim($str);

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

print_r($strArray);

  • 6
    This only strips whitespace from the beginning and end of a string, not between each colour. – SeanWM Aug 03 '15 at 12:46