如何在PHP中用一个空格正确替换多个空格?

时间:2016-10-26 14:05:35

标签: php regex unicode

我正在搜索SO答案,发现大多数替换多个空格的解决方案是:

$new_str = preg_replace("/\s+/", " ", $str);

但在很多情况下,空格字符包括UTF字符,包括换行符,换页符,回车符,不间断空格等。 This wiki 描述UTF定义二十五个字符定义为空格。

那么我们如何使用正则表达式替换所有这些字符呢?

3 个答案:

答案 0 :(得分:3)

传递u修饰符时,\s变为支持Unicode。因此,一个简单的解决方案是使用

$new_str = preg_replace("/\s+/u", " ", $str);
                             ^^

请参阅PHP online demo

答案 1 :(得分:0)

要做的第一件事是阅读 this 解释如何在正则表达式中处理unicode。专门针对PHP,我们需要首先包括PCRE修饰符' u'让引擎识别UTF字符。所以这将是:

$pattern = "/<our-pattern-here>/u";

接下来要注意的是,在PHP中,unicode字符具有模式\x{00A0},其中00A0non-breaking space的十六进制表示。因此,如果我们想用一个空格替换连续的不间断空格,我们就会:

$pattern = "/\x{00A0}+/u";
$new_str = preg_replace($pattern," ",$str);

如果我们要包含wiki中提到的其他类型的空格,例如:

  • \x{000D}回车
  • \x{000C}表单Feed
  • \x{0085}下一行

我们的模式变为:

$pattern = "/[\x{00A0}\x{000D}\x{000C}\x{0085}]+/u";

但这真的不是很好,因为正则表达式引擎将永远需要找出这些字符的所有组合。这是因为字符包含在方括号[]中,并且我们在一次或多次出现时都有一个+。

然后获得更快结果的更好方法是首先用普通空格替换每个字符的所有出现次数。然后用一个正常空间替换多个空格。我们删除[] +,然后使用或运算符|分隔字符:

$pattern = "/\x{00A0}|\x{000D}|\x{000C}|\x{0085}/u";
$new_str = preg_replace($pattern," ",$str); // we have one-to-one replacement of character by a normal space, so 5 unicode chars give 5 normal spaces
$final_str = preg_replace("/\s+/", " ", $new_str); // multiple normal spaces now become single normal space

答案 2 :(得分:0)

all Unicode whitespaces匹配的模式为[\pZ\pC]。这是unit test to prove it

如果您正在解析UTF-8中的用户输入并需要对其进行规范化,那么将匹配基于该列表非常重要。所以回答你的问题:

$new_str = preg_replace("/[\pZ\pC]+/u", " ", $str);