从字符串中删除所有空白字符

84
我知道在PHP.net上有这个评论。
我想要一个类似的工具,就像PHP中的tr一样,这样我就可以简单地运行。
tr -d " " ""

我运行了函数php_strip_whitespace但没有成功。
$tags_trimmed = php_strip_whitespace($tags);

我也尝试运行正则表达式函数,但不成功。
$tags_trimmed = preg_replace(" ", "", $tags);

可能是重复的问题:无法使用str_replace()从PHP字符串中删除空格 - T.Todua
1
@taztodgmail 看看日期。这是2009年,另一个是2013年。2013年的是这个的副本。 - Léo Léopold Hertz 준영
1
FYI:\s标志不包括utf-8字符,例如utf-8编码的nbsp;、ps、quads和fs。https://dev59.com/0HE95IYBdhLWcg3wn_Vr - ppostma1
1
当然可以!我有一组代码可以解决这个问题。 - ppostma1
为什么这个弹出窗口会出现在前台页面? - Jonathan DS
16个回答

136

为了去除任何空白字符,您可以使用正则表达式。

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

另外请参见此答案,该答案可以处理UTF-8字符串中的空格。


Kathir,它失败的输入是什么? - Alex
为什么人们总是把 + 放在 s 后面?对于这个你不需要它。 - Buttle Butkus
2
这是比逐个替换快上一个数量级的原因 :) - Paul Dixon
1
听起来你正在尝试解决与 OP 不同的问题。这是一个从字符串中删除所有空格的解决方案。 - Paul Dixon
我们是否应该根据ppostma指示的空格集来扩展您的答案? - Léo Léopold Hertz 준영
显示剩余2条评论

54
正则表达式默认情况下不支持UTF-8字符。元字符\s只能匹配原始的拉丁字符集。因此,以下命令只能移除制表符、空格、回车和换行符。
// https://dev59.com/YHM_5IYBdhLWcg3wq1GF#1279798
$str=preg_replace('/\s+/', '', $str);

随着UTF-8变得主流,当遇到新的UTF-8字符时,这个表达式会更频繁地失败/停止,留下无法被\s识别的空白字符。
为了处理Unicode/UTF-8引入的新类型空白字符,需要一个更广泛的字符串来匹配和删除现代空白字符。
由于正则表达式默认不识别多字节字符,只能使用一个分隔的元字符串来识别它们,以防止字节段被其他utf-8字符中的\x80替换(四元组中的\x80可以替换智能引号中的所有\x80子字节)。
$cleanedstr = preg_replace(
    "/(\t|\n|\v|\f|\r| |\xC2\x85|\xc2\xa0|\xe1\xa0\x8e|\xe2\x80[\x80-\x8D]|\xe2\x80\xa8|\xe2\x80\xa9|\xe2\x80\xaF|\xe2\x81\x9f|\xe2\x81\xa0|\xe3\x80\x80|\xef\xbb\xbf)+/",
    "_",
    $str
);

这个功能会处理并删除制表符、换行符、垂直制表符、换页符、回车符、空格,以及从这里额外删除的内容:

下一行、不间断空格、蒙古语元音分隔符,[四分之一em空格、半个em空格、一个em空格、一个en空格、三分之一em空格、四分之一em空格、六分之一em空格、数字空格、标点空格、窄空格、短空格、零宽空格、零宽非连接符、零宽连接符],行分隔符、段落分隔符、窄不换行空格、中等数学空格、词连接符、表意空格,以及零宽不换行空格。

许多这些字符在从自动化工具或网站导出的XML文件中会造成混乱,影响文本搜索和识别,并且可能被无形地粘贴到PHP源代码中,导致解析器“跳到下一个命令”(段落和行分隔符),从而导致代码行被跳过,引发间歇性的、无法解释的错误,我们开始称之为“文本传播疾病”。

(从网页上复制粘贴已经不安全了。使用字符扫描器来保护您的代码。哈哈)


1
像这样吗?我试图解释原来的方法不再像应该的那样工作了。 - ppostma1
太好了!您能否包括您的集合中字符的数量?这将有助于我们确定您确实拥有完整的字符集。我接受了您的答案,因为它现在比旧的被接受的答案更完整。 - Léo Léopold Hertz 준영
1
谢谢,但是使用 trim() 应该是正确的答案。 - Husam
1
正则表达式中应该不应该有 u 标志? - user5147563
这并不是必要的,因为它使用了固定字符串和交替符:| 如果在字符集中正确地完成,例如 [\t\n\r\xC2\x85\xa0],那么它需要一个 /u 来表示 utf-8 字符串是多字节的(或者它将从源文本中剥离每个单独出现的 \xC2、\x85 和 \xa0)。但是字符集版本不太容易阅读。 - ppostma1
显示剩余2条评论

27
有时您需要删除连续的空格。您可以这样做:

有时您需要删除连续的空格。您可以这样做:

$str = "My   name    is";
$str = preg_replace('/\s\s+/', ' ', $str);

输出:

My name is

谢谢。这正是我正在寻找的。 - lomse
这是对一个不同问题的正确答案。模式可以是/\s{2,}/,但你的模式和我的模式不能将一个制表符标准化为一个空格。也许更好的做法是消耗所有出现一次或多次的空白字符。/\s+/ - undefined

16
$string = str_replace(" ", "", $string);

我认为 preg_replace 会寻找像 [:space:] 这样的内容


8
您可以使用 PHP 中的 trim 函数来修剪字符串两侧(左侧和右侧)。
 trim($yourinputdata," ");

或者

trim($yourinputdata);

您可以使用以下内容:

您还可以使用

ltrim() - Removes whitespace or other predefined characters from the left side of a string
rtrim() - Removes whitespace or other predefined characters from the right side of a string

系统:PHP 4、5、7
文档:http://php.net/manual/zh/function.trim.php


(翻译说明:此文本主要是介绍PHP语言的trim函数,系统支持的版本包括PHP 4、5、7。文档链接指向中文版的trim函数说明页面。)

1
这应该是正确的答案,因为它本地化地、精确地完成了 OP 所要求的任务。它很小巧、干净,并且可以通过添加要修剪的额外字符来“扩展”。 - Louis Loudog Trottier
2
Trim 不会删除字符串内部的空格,只会删除左右两侧的空格。顺便说一下,默认情况下 Trim 会删除空格,所以你不需要提供第二个参数。 - user5147563

6

如果您想从$tags中完全删除所有空格,为什么不直接使用以下方法:

str_replace(' ', '', $tags);

如果您想去除换行符等,那就需要做更多的工作...


2
如果您不将结果分配给一个变量,这实际上并没有做任何有用的事情。 - Paul Dixon

2

有可能的解决方案是使用自定义文件包装器来模拟变量作为文件。您可以通过使用以下方式实现:

1)首先,在文件内注册您的包装器(仅在文件中注册一次,就像 session_start() 一样使用它):

stream_wrapper_register('var', VarWrapper);

2) 然后定义您的包装类(它写得非常快,不完全正确,但它可以工作):

class VarWrapper {
  protected $pos = 0;
  protected $content;
  public function stream_open($path, $mode, $options, &$opened_path) {
    $varname = substr($path, 6);
    global $$varname;
    $this->content = $$varname;
    return true;
  }
  public function stream_read($count) {
    $s = substr($this->content, $this->pos, $count);
    $this->pos += $count;
    return $s;
  }
  public function stream_stat() {
    $f = fopen(__file__, 'rb');
    $a = fstat($f);
    fclose($f);
    if (isset($a[7])) $a[7] = strlen($this->content);
    return $a;
  }
}

3) 然后使用任何文件函数与您的 var:// 协议包装器(您也可以将其用于包括、要求等):

global $__myVar;
$__myVar = 'Enter tags here';
$data = php_strip_whitespace('var://__myVar');

注意:不要忘记将变量放在全局范围内(例如全局变量$__myVar)。

1
这很复杂,初学者可能不想看。但为了表现出你的努力,我会给你点赞,这样这篇文章中的-1就会被移除。 - Ironwind
1
是的,我知道它非常复杂,但它确实有效,在某些情况下非常强大。不幸的是,这是唯一的方法(而不是创建丑陋的临时文件),可以将变量发送到仅使用文件的函数中(php_strip_whitespace并不是唯一的函数)。例如,您可以在require之前替换代码-您可以为PHP创建自己的“预编译器”,在其中可以做任何想做的事情。我使用它,并且在多年的编程过程中变得非常强大和有用。 - micropro.cz
1
global $$varname; 在2013年是多么可怕。 - B001ᛦ

2

这是一篇旧文章,但最短的答案没有列在这里,所以我现在添加它。

strtr($str,[' '=>'']);

另一种常见的方法是使用explode和implode来实现:

implode('',explode(' ', $str));


这将消除字面上的空格,但不会消除所有的空白字符(如制表符、换行符和回车符)。 - undefined

0

你还可以使用preg_replace_callback函数。这个函数与它的兄弟函数preg_replace相同,除了它可以接受一个回调函数,让你对输出进行更多的控制。

$str = "this is a   string";

echo preg_replace_callback(
        '/\s+/',
        function ($matches) {
            return "";
        },
        $str
      );

1
在 Stack Overflow 上,为什么你的解决方案有效的解释是一个好的实践。更多信息请阅读 如何回答 - Samuel Liew
你能否提供一些例子说明preg_replace的回调函数在哪些情况下有用? - Léo Léopold Hertz 준영
因为preg_replace()完全能够用空字符串替换匹配到的字符串,所以没有什么好的理由使用preg_replace_callback()来解决这个问题。 - undefined

0
$string = trim(preg_replace('/\s+/','',$string));

trim()方法是多余的——正则表达式模式会在trim()有机会之前消除字符串中的所有空格。这个没有解释的代码片段对这个页面没有任何新的价值。 - undefined

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