去除多个空格

255

我从MySQL数据库中获取$row['message'],需要去除所有的空格,如\n \t等。

$row['message'] = "This is   a Text \n and so on \t     Text text.";

应该格式化为:
$row['message'] = 'This is a Text and so on Text text.';

我尝试过:

 $ro = preg_replace('/\s\s+/', ' ',$row['message']);
 echo $ro;

但是它并不能去掉\n\t,只能去掉单个空格。有谁能告诉我如何做到这一点吗?


2
换行符和制表符都在单引号中,所以您想要它们字面上的意思吗? - Mark Lalor
我通过将引号更改为双引号来修复了代码部分的引用,包括\n和\t。 - Buttle Butkus
15个回答

464

您需要:

$ro = preg_replace('/\s+/', ' ', $row['message']);

您正在使用的是 \s\s+,它表示空格(空格、制表符或换行符)后面跟着一个或多个空格。这实际上意味着用单个空格替换两个或多个空格。

您想要的是将一个或多个空格替换为单个空格,因此您可以使用模式\s\s*\s+(推荐)


2
他的方法比这个更好:你为什么要用一个空格替换另一个空格呢? - nickf
19
他还希望将 \n 和 \t 替换为空格。现在他的模式与它们不匹配,例如 $x = "does\nthis\twork";原帖作者希望所有空格都替换为一个空格。 - codaddict
1
@codaddict,我们如何保留 \n 并从字符串中删除所有其他多余的空格和制表符?请帮帮我。 - Mansoorkhan Cherupuzha
1
你能更具体地解释为什么推荐使用"\s+"吗? - Isius
8
注意,在 PHP 中,\s 不包括 "vertical tab" chr(11)。如果想要包括它,你需要使用 space 字符类:[[:space:]]+。参考链接:http://www.php.net/manual/en/regexp.reference.character-classes.php。 - Yaroslav
显示剩余7条评论

79
<?php
$str = "This is  a string       with
spaces, tabs and newlines present";

$stripped = preg_replace(array('/\s{2,}/', '/[\t\n]/'), ' ', $str);

echo $str;
echo "\n---\n";
echo "$stripped";
?>

这将输出

This is  a string   with
spaces, tabs and newlines present
---
This is a string with spaces, tabs and newlines present

18
preg_replace('/[\s]+/mu', ' ', $var);

\s 已经包含制表符和换行符,所以上述正则表达式似乎已经足够了。


2
这里不需要使用方括号,因为它们内部只有一件事情。由于没有^$锚点,所以/m不会起作用,而/u除了略微减慢速度并在输入字符串无效的情况下崩溃之外,不会产生任何影响(它不会影响\s匹配,但会影响\pZ)。 - thomasrutter

15

简化为一个函数:

function removeWhiteSpace($text)
{
    $text = preg_replace('/[\t\n\r\0\x0B]/', '', $text);
    $text = preg_replace('/([\s])\1+/', ' ', $text);
    $text = trim($text);
    return $text;
}

基于Daniel O'Neal的回答。

10
我无法在此处复制该问题:
$x = "this    \n \t\t \n    works.";
var_dump(preg_replace('/\s\s+/', ' ', $x));
// string(11) "this works."

我不确定这是否只是一个抄录错误,但在您的示例中,您使用了单引号字符串。只有在双引号字符串中,\n\t才被视为换行符和制表符。也就是说:

'\n\t' != "\n\t"

编辑: 正如Codaddict指出的那样,\s\s+不能替换单个制表符。然而,我仍然认为使用\s+不是一种高效的解决方案,所以我们可以考虑这种方式:

preg_replace('/(?:\s\s+|\n|\t)/', ' ', $x);

3
+1, True. 对于含有大量单空格的字符串(通常情况下是这样),用空格替换空格是低效的。 - codaddict
2
@coaddict:为了测试你的假设,我写了一个快速脚本来运行1000次每个替换,并检查每个替换的时间。对于字符串 **'+1, True. 对于有大量单空格的字符串(通常是这种情况),用空格替换空格是低效的。- codaddict Feb 24 '10 at 13:32'**,一千个 \s+ preg_replace() 调用花费了0.010547876358032秒,而一千个 (?:\s\s+|\n|\t) preg_replace() 调用花费了0.013049125671387秒,使其减慢了近30%。 - Joseph Cheek
你可能需要在最后一个示例中添加“\r”,因为某些计算机确实会单独使用“\r”(苹果Mac?) - thomasrutter

10
$str='This is   a Text \n and so on Text text.';
print preg_replace("/[[:blank:]]+/"," ",$str);

3
这是对我最有效的方法。此外,我会添加修剪(trim)来删除字符串开头和结尾的空格。 - Dziamid
1
@Dziamid 你可以使用 trim(preg_replace(...)) 来完成它。 - Balázs Varga

6
preg_replace('/(\s\s+|\t|\n)/', ' ', $row['message']);

这将用单个空格替换所有制表符、所有换行符以及多个空格、制表符和换行符的组合。


\t\n已经包含在\s中,因此您的正则表达式与\s\s+完全相同,最好写成\s{2,},就像@Alex Polo answer所说。 - Toto
我需要与原问题相同的功能,但不替换单个空格为单个空格字符,这就是解决方案。 - 6opko

4

没有 preg_replace() 函数

$str = "This is   a Text \n and so on \t     Text text.";
$str = str_replace(["\r", "\n", "\t"], " ", $str);
while (strpos($str, "  ") !== false)
{
    $str = str_replace("  ", " ", $str);
}
echo $str;

4
<?php
#This should help some newbies
# REGEX NOTES FROM DANUEL
# I wrote these functions for my own php framework
# Feel Free to make it better
# If it gets more complicated than this. You need to do more software engineering/logic.
# (.)  // capture any character
# \1   // if it is followed by itself
# +    // one or more

class whitespace{

    static function remove_doublewhitespace($s = null){
           return  $ret = preg_replace('/([\s])\1+/', ' ', $s);
    }

    static function remove_whitespace($s = null){
           return $ret = preg_replace('/[\s]+/', '', $s );
    }

    static function remove_whitespace_feed( $s = null){
           return $ret = preg_replace('/[\t\n\r\0\x0B]/', '', $s);
    }

    static function smart_clean($s = null){
           return $ret = trim( self::remove_doublewhitespace( self::remove_whitespace_feed($s) ) );
    }
}
$string = " Hey   yo, what's \t\n\tthe sc\r\nen\n\tario! \n";
echo whitespace::smart_clean($string);

3
静态函数 remove_whitespace 的作用是什么?你定义了它但从未使用过。 - Lukas Liesis
1
这些都有它们的用途,但是没有一个能够实现问题所要求的,即将多个连续的空格替换为一个。你的“remove_doublewhitespace”只会替换相同的多个空格字符,因此它会将“\n\n\n”替换为一个空格,但对于“ \r\n”则不会有任何作用。 - thomasrutter

3
这是我会使用的方法:

a. 确保使用双引号,例如:

$row['message'] = "This is   a Text \n and so on \t     Text text.";
b. 去除额外的空格,可以使用以下方法:
$ro = preg_replace('/\s+/', ' ', $row['message']); 
echo $ro;

这可能不是最快的解决方案,但我认为它需要的代码最少,而且应该可以工作。虽然我从未使用过mysql,所以我可能是错的。


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