最近遇到一个非常奇怪的问题,我的数据库包含的字符串看起来是正常的空白字符,但实际上是其他字符。
例如,将
trim()
应用于字符串:
"TEST "
让我着迷:
"TEST "
结果。 所以我复制并粘贴字符串中的最后一个字符:
echo ord(' ');
194
194? 根据 ASCII 表,应该是
┬
。 所以我现在很困惑。 为什么这个字符看起来是空格?当 trim()
失败时,我如何才能像这样的 trim()
字符?
它更有可能是一个两字节的
194
160
序列,它是 NO-BREAK SPACE 代码点的 UTF-8 编码(相当于 HTML 中的
实体)。
这实际上不是一个空间,尽管它看起来像一个空间。 (例如,您会发现它不会自动换行。) \s 的正则表达式匹配会匹配它,但与空格的简单比较则不会;
trim()
也不会删除它。
要将 NO-BREAK 空格替换为普通空格,您应该能够执行以下操作:
$string = str_replace("\u{c2a0}", " ", $string);
或
$string = str_replace("\u{c2a0}", "", $string);
删除它们
你可以尝试:
PHP 修剪
$foo = "TEST ";
$foo = trim($foo);
PHP str_replace
$foo = "TEST ";
$foo = str_replace(chr(194), '', $foo);
重要提示:您可以尝试使用
或chr(194).chr(160)
'\u00A0'
PHP preg_replace
$foo = "TEST ";
$foo = preg_replace('#(^\s+|\s+$)#', '', $foo);
或者(我不确定它是否会很好用)
$foo = "TEST ";
$foo = preg_replace('#[\xC2\xA0]#', '', $foo);
有同样的问题。解决了它
trim($str, ' ' . chr(194) . chr(160))
您可能从 Excel/CSV 获得了原始数据..我正在从这种格式导入到我的 mysql 数据库,我花了几个小时才弄清楚为什么它被填充并且修剪似乎不起作用(必须检查每个字符在每个 CSV 列字符串中),但实际上 Excel 似乎添加了 chr(32) + chr (194) + chr(160) 来“填充”该列,乍一看,该列看起来像是末尾的所有空格。这就是让我有一个漂亮、完美的字符串加载到数据库中的方法:
// convert to utf8
$value = iconv("ISO-8859-15", "UTF-8",$data[$c]);
// excel adds 194+160 to fill up!
$value = rtrim($value,chr(32).chr(194).chr(160));
// sanitize (escape etc)
$value = $dbc->sanitize($value);
php -r 'print_r(json_encode(" "));'
"\u00a0"
$string = str_replace("\u{00a0}", "", $string); //not \u{c2a0}
我需要在 PHP 中修剪字符串并得到相同的结果。
通过马克贝克斯的回答发现原因后,我用以下内容代替
trim
:
// $str = trim($str); // won't strip UTF-8 encoded nonbreaking spaces
$str = preg_replace('/^(\\s|\\xC2\\xA0)+|(\\s|\\xC2\\xA0)+$/', '', $str);
我认为我应该提供自己的答案,因为我现在已经清楚发生了什么。 问题源于处理包含不间断空格实体
的html。 一旦您将内容加载到 php 的 DOMDocument()
中,所有实体都会转换为其解码值,并且在解析它时,您最终会得到一个不间断的空格字符。 无论如何,即使在不同的场景中,以下方法是将它们转换为常规空格的另一种选择:
$foo = str_replace(' ',' ',htmlentities($foo));
首先将不间断空格转换为 html 实体,然后转换为常规空格。 现在可以像平常一样轻松修剪
$foo
的内容。
在尝试了所有这些示例但没有成功之后,我将代码从 00a0 大写到 00A0,它终于起作用了
$text = str_replace("\u{00A0}", " ", $text);