先来判断下这段代码的输出是否一致?
$string = '沈唁 ';
var_dump(trim($string));
var_dump(preg_replace('/^[\s\0]+|[\s\0]+$/u', '', $string));
如果你觉得是一致的,那么就是大错特错了。
在日常工作中,经常需要处理字符串。其中一种常用的情况是,需要删除字符串两端的空白字符,这就是 trim()
函数原本的作用。
但是标准的 trim()
函数不能处理多字节字符。
什么是trim()
函数?
在#PHP#中, trim()
函数用于删除字符串的开头和结尾的空白字符。默认情况下,这些字符包括:
"\0"
- NULL"\t"
- 制表符"\n"
- 换行"\v"
- 垂直制表符"\r"
- 回车" "
- 空格
mbstring
扩展
在很多语言中,每个必要字符都能一对一映射到 8 bit
的值,但也有一些语言需要非常多的字符来书面通讯,以至于它们的编码范围不能仅仅包含在一个字节里。
开发多字节字符编码方案是为了在基于字节的常规编码系统中表达超过 256 个字符。
在使用trim
、split
、splice
等等操作多字节编码的字符串的时候,特别需要注意,由于在这种编码方案下,两个或多个连续字节可能只表达了一个字符,所以需要使用专门的函数。 否则,你可能会得到一个以乱码的字符串结尾。
而 mbstring
提供了针对多字节字符串的函数,能够帮开发者处理 PHP 中的多字节编码。
mbstring
扩展的使用和普通字符串操作函数一致,而且仅仅需要加上mb_
前缀即可。
类似于:
split
=>mb_split
strlen
=>mb_strlen
substr
=>mb_substr
以此类推,trim
是不是可以直接改为调用mb_trim
?
答案是也不是。因为你可能会得到一个错误:
PHP Fatal error: Uncaught Error: Call to undefined function mb_trim()
mb_trim
、mb_ltrim
和 mb_rtrim
从 2022 年 8 月份就有人在 php-src 的 issue 进行了反馈,这三个函数也是前不久刚刚通过 RFC,合并到 PHP 内核中新增的。
https://github.com/php/php-src/commit/a80b6d7b99ae885cb450a563a788f57917cef74e
function mb_trim(string $string, string $characters = " \f\n\r\t\v\x00\u{00A0}\u{1680}\u{2000}\u{2001}\u{2002}\u{2003}\u{2004}\u{2005}\u{2006}\u{2007}\u{2008}\u{2009}\u{200A}\u{2028}\u{2029}\u{202F}\u{205F}\u{3000}\u{0085}\u{180E}"): string
function mb_ltrim(string $string, string $characters = " \f\n\r\t\v\x00\u{00A0}\u{1680}\u{2000}\u{2001}\u{2002}\u{2003}\u{2004}\u{2005}\u{2006}\u{2007}\u{2008}\u{2009}\u{200A}\u{2028}\u{2029}\u{202F}\u{205F}\u{3000}\u{0085}\u{180E}", ?string $encoding = null): string
function mb_rtrim(string $string, string $characters = " \f\n\r\t\v\x00\u{00A0}\u{1680}\u{2000}\u{2001}\u{2002}\u{2003}\u{2004}\u{2005}\u{2006}\u{2007}\u{2008}\u{2009}\u{200A}\u{2028}\u{2029}\u{202F}\u{205F}\u{3000}\u{0085}\u{180E}", ?string $encoding = null): string
所以虽然 8.3 刚发布,但是 8.3 中确实没有这三个函数,可能需要在 8.3.1 中才能使用了。
不过 PHP 足够灵活,使我们能够根据需要创建自定义的函数,如多字节 mb_trim()
函数。
if (!function_exists('mb_trim')) {
function mb_trim($string)
{
return preg_replace('/^[\s\0]+|[\s\0]+$/u', '', $string);
}
}
$string = ‘沈唁 ’ 这里的空格是什么样的空格啊
@superdog 就是普通空格。。
@沈唁 提取了一下字符串,网页上给出的空格是 U+3000 IDEOGRAPHIC SPACE. 技术上来说确实是空格(Unicode 属性 `White_Space=yes`),但是并不普通(不是 U+0020 SPACE)