php中使用preg_replace替换中文,加了u模式,依然乱码的问题

游北亮
博客专家认证
2017-09-05 09:34:00
之前用trim,发现有一些nbsp这种的空格,以及中文空格,会无法trim,手工给trim设置第2个参数,会导致中文乱码,
后来改行 preg_replace,并使用u模式,代码很简单如下,结果还是会有问题:
$str = '破千魂';
$str2 = preg_replace('/(^\s*)|(\s*$)/u', '', $str);
var_dump($str);
var_dump($str2); // str2变成了NULL


为啥呢?后来又发现把\s* 改成 \s+就正常了,可是为啥呢?
在其它语言里,工作的好好的正则,为啥在php里就这么奇怪呢?
...全文
993 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
游北亮 2017-09-05
  • 打赏
  • 举报
回复
感谢楼上,\s已经包含了 nbsp的情况,我的问题是为什么这段代码会导至结果为NULL了:
$str = '破千魂';
$str2 = preg_replace('/(^\s*)|(\s*$)/u', '', $str);
var_dump($str);
var_dump($str2); // str2变成了NULL
hongmei85 2017-09-05
  • 打赏
  • 举报
回复
试下

$str = '破千魂';
$str2 = preg_replace('/(^(\s| )+)|((\s| )+$)/u', '', $str);
var_dump($str);
var_dump($str2); // str2变成了NULL
游北亮 2017-09-05
  • 打赏
  • 举报
回复
引用 1 楼 xuzuning 的回复:
使用u模式时,源串必须是 utf-8 字符集的 你的 /(^\s*)|(\s*$)/ 规则串不可能匹配  这种的空格,不要自欺欺人
文件本身是存为utf8格式,你意思是说:破千魂 这3个字不是utf8? 另外,nbsp这种空格入库后变成了 chr(0xc2) . chr(0xa0) 用trim($str, chr(0xc2) . chr(0xa0)) 肯定是会乱码的, 而用正则 \s 是可以替换掉这2个字符的
xuzuning 2017-09-05
  • 打赏
  • 举报
回复
使用u模式时,源串必须是 utf-8 字符集的 你的 /(^\s*)|(\s*$)/ 规则串不可能匹配  这种的空格,不要自欺欺人
游北亮 2017-09-05
  • 打赏
  • 举报
回复
引用 11 楼 xuzuning 的回复:
php 早就停止了对 php5.4 的维护了,php5.4 的最后一个版本是 php5.4.45 你怎么就知道没有被改正了呢? 就算是你发现了bug,但你也并没有修正的能力,那么发现了也是枉然
特意去下载了一个php5.4.45,编译后,发现果然没有这个bug了, 我的5.4.33只能继续用着了…… 我一开始以为是不是代码要加什么特别的处理, 感谢版主了
专注于服务器 2017-09-05
  • 打赏
  • 举报
回复
乱码的问题,总体来说,原因需要慢慢排查,有些时候,就是很奇怪,很难找到原因。 https://promotion.aliyun.com/ntms/act/ambassador/sharetouser.html?userCode=5uqvqirt&productCode=vm&utm_source=5uqvqirt
xuzuning 2017-09-05
  • 打赏
  • 举报
回复
php 早就停止了对 php5.4 的维护了,php5.4 的最后一个版本是 php5.4.45 你怎么就知道没有被改正了呢? 就算是你发现了bug,但你也并没有修正的能力,那么发现了也是枉然
游北亮 2017-09-05
  • 打赏
  • 举报
回复
引用 9 楼 xuzuning 的回复:
^\s* 改为 ^\s+ 这个规则本意就是匹配首部的空白字符,写作 ^\s* 是没道理的
嗯,是的,\s*会导致每次都有替换动作,\s+只有存在才进行替换, 只是因为出现NULL,我以为是特殊情况, 现在应该确认是php5.4才有的bug了
xuzuning 2017-09-05
  • 打赏
  • 举报
回复
^\s* 改为 ^\s+ 这个规则本意就是匹配首部的空白字符,写作 ^\s* 是没道理的
游北亮 2017-09-05
  • 打赏
  • 举报
回复
引用 7 楼 xuzuning 的回复:
$str = ' 破千魂 ';//我都是用 gbk的9节约空间)
$str = iconv('gbk', 'utf-8', $str).chr(0xc2) . chr(0xa0);
$str2 = preg_replace('/(^\s*)|(\s*$)/u', '', $str);
var_dump($str);
var_dump($str2); // str2变成了NULL
string(13) " 破千魂  "
string(9) "破千魂"
前面不能加空格,第一个字符只要是“破”,在php5.4.33下,问题必现
xuzuning 2017-09-05
  • 打赏
  • 举报
回复
$str = ' 破千魂 ';//我都是用 gbk的9节约空间)
$str = iconv('gbk', 'utf-8', $str).chr(0xc2) . chr(0xa0);
$str2 = preg_replace('/(^\s*)|(\s*$)/u', '', $str);
var_dump($str);
var_dump($str2); // str2变成了NULL
string(13) " 破千魂  "
string(9) "破千魂"
游北亮 2017-09-05
  • 打赏
  • 举报
回复
又验证了一下手上的几个版本,php5.2正常,hhvm也正常, php5.4下必现的问题, 难道是php5.4的bug?
游北亮 2017-09-05
  • 打赏
  • 举报
回复
引用 1 楼 xuzuning 的回复:
使用u模式时,源串必须是 utf-8 字符集的 你的 /(^\s*)|(\s*$)/ 规则串不可能匹配  这种的空格,不要自欺欺人
我特意测试了一下编辑,确实是UTF-8的
 $str = '破千魂';
 $code = mb_detect_encoding($str, array('UTF-8','GB2312','GBK'));
 var_dump($code);
 $str2 = preg_replace('/(^\s*)|(\s*$)/u', '', $str);
 var_dump($str);
 var_dump($str2);
输出是: string(5) "UTF-8" string(9) "破千魂" NULL

21,886

社区成员

发帖
与我相关
我的任务
社区描述
从PHP安装配置,PHP入门,PHP基础到PHP应用
社区管理员
  • 基础编程社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧