在逗号处分割字符串并修剪每个值的潜在空格

220
例如,我想从这个字符串中的元素创建一个数组:
$str = 'red,     green,     blue ,orange';

我知道你可以对它们进行分割、循环和修整:

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

但我感觉有一种简单的方法可以处理这个问题。你有什么想法吗?

11个回答

581

你可以使用array_map来执行以下操作:

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

12
这也是由PHP内部循环执行的。 - Jason OOO
5
我认为在大多数人的看法中,牺牲几毫秒(如果有的话)是一种公平的权衡,以获得一行简短、简单易读的代码。 - Gavin
2
简单易懂。但是,如果处理大数据集,则@amr-eladwy提供的更高效的答案是更好的解决方案。 - Yaron

73

一个更好的答案

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

结果:

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

这个功能:

  • 只按逗号进行分割
  • 去除每个条目中的空白字符。
  • 忽略空项目
  • 不会分割带有内部空格的项目,如“green thing”

8
有人能解释一下为什么这个答案没有100个赞吗?正则表达式很难理解,但它比其他解决方案更快地解析了我那个100MB的文件。 - Dan
2
抱歉,但这个正则表达式是错误的 - 请尝试用 *red* 替换 red。更好的正则表达式可能是 /(\s*,\s*)+/。 - Greg
@AmrElAdawy,提醒一下,8/28更新后这个方法不再适用。使用答案中的正则表达式时,某些元素中的空格未被修剪。例如: green thing - Samsquanch
1
@Samsquanch 已更新。如果您发现任何问题,请告知我。 - Amr Eladawy
1
为什么你的正则表达式没有去除字符串周围的空格?例如: ' 红色,绿色物品,蓝色,橙色 ' - wp-mario.ru
显示剩余2条评论

27
以下代码还会处理输入字符串开头/结尾的空格:
$new_arr = preg_split('/\s*,\s*/', trim($str));

这是一个最简测试,其中每个合理位置都有空格:

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

由于 array_map 和正则表达式解决方案产生相同的结果,有人能比较它们的性能吗? - Dan
@Dan 对于这种情况,没有任何区别。 - Aris

9
这是如何在一行代码中同时替换和拆分的方法。
$str = 'red,     green,     blue ,orange';

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

将以以下方式输出结果

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

2
这是将字符串中的空格删除的程序相关内容。例如,'navy blue' 变成 'naviblue'。 - manian

6
通过结合已有答案中的一些原则,我得出了以下结论。
preg_split ('/\s*,+\s*/', 'red,     green thing ,,  ,,   blue ,orange', NULL, PREG_SPLIT_NO_EMPTY);

这样做的原因是我发现了这个答案中的一个错误,如果字符串末尾有逗号,它将返回一个空元素数组。例如:
preg_split ('/(\s*,*\s*)*,+(\s*,*\s*)*/', 'red,     green thing ,,  ,,   blue ,orange,');

结果在

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

你可以使用PREG_SPLIT_NO_EMPTY,如此答案所述,以去除它,从而解决这个问题。但一旦你这样做了,就没有必要通过正则表达式删除连续的逗号,因此简化了表达式。

3
您可以使用一行正则表达式来完成此操作。
preg_split('@(?:\s*,\s*|^\s*|\s*$)@', $str, NULL, PREG_SPLIT_NO_EMPTY);

它可以在字符串中创建多个空格的匹配,例如“ one,two,three ”会生成以下数组: ( [0] => [1] => one [2] => two [3] => three [4] => [5] => ) - Tamik Soziev
它在字符串中创建了多个匹配项,用于空格之前和之后的空格,例如 " one, two, three " 生成:Array ( [0] => [1] => one [2] => two [3] => three [4] => [5] => ) - undefined

1

具体来说,针对OP提供的样本字符串,因为每个要匹配的子字符串都是单词,你可以使用str_word_count()函数。

代码:(演示

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

输出:

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

如果你仔细阅读细则,这个方法也可以用于除字母(和一些连字符和撇号)以外的子字符串,只需将所需字符添加到字符掩码/第三个参数中即可。

代码:(演示)

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

输出:

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

因为示例字符串的限制,我将非常狭隘地处理这个问题,但这将提供相同的期望输出:

代码:(演示)

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

最后,如果你想在逗号上进行分割,并带有可选的前导或尾随空格,这是调用方式:(演示)
var_export(
    preg_split ('/ *,+ */', $str, 0, PREG_SPLIT_NO_EMPTY)
);

1
尝试这个:

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

OP想要一个数组。preg_replace()不能从字符串生成一个数组。这是对错误问题的正确回答。被踩了。 - mickmackusa
1
$list = preg_split("/\s*,\s*/", 'red, green, blue ,orange'); 通过轻微修改,可以修正答案。 - dreftymac

0

你可以使用 preg_split() 函数来实现此操作。

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

/* Result:
  Array
  (
      [0] => red
      [1] => green
      [2] => blue
      [3] => orange
  )
 */

1
这将在您的元素中按空格拆分。 - Chris KL
将逗号移动到方括号左侧,使逗号成为必需的。 - Eric Leschinski
把逗号往左移并不能解决这个问题。请检查我下面的答案 https://dev59.com/22Ik5IYBdhLWcg3wWtBz#38300330 - Amr Eladawy

-4
$str = str_replace(" ","", $str);

4
Trim 做的不仅仅是这个... 它还会修剪 \t\n\r\0\x0B - Arian Faurtosh
3
不仅如此,这还会破坏带有空格的元素。 - Adam Kiss

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接