从一个bug谈rtrim

今天遇到一个bug,代码很简单:

<?php
$src = '战争片';
$result = rtrim($src, '片');
echo mb_convert_encoding($result, 'gbk', 'utf-8'),"\n";
本来以为得到的结果会是“战争”,但实际输出的却只有“战”。
不明所以,以为是 rtrim 的问题。查了一下,原来是自己对 rtrim 的理解有误。

rtrim 函数原型: string rtrim ( string str [, string charlist] )
仔细看了下手册中charlist的解释:
You can also specify the characters you want to strip, by means of the charlist parameter. Simply list all characters that you want to be stripped.
它的实际意思应该是:以每个字符为单位从目标字符串的右端开始查找,如果该字符在 trim 函数的第二个参数中,就将其删掉,直到当前字符不在参数列表中为止。而并非是我先前以为的:从str 的串尾去掉固定字串charlist。

用一个例子具体说明:

<?php
$src = 'test.rtrim';
$rtrimList = 'trim';
$result = rtrim($src, $rtrimList);
echo $result, "\n";
rtrim 做的工作是:从 $src 中取出最后一个字符“ m ”,发现“ m ”在$rtrimList 中,于是去掉;再取出“i ”,发现“ i ”也在$rtrimList 中,也去掉,... 依次向左,直到进行到“ . ”,发现“ . ”不在$rtrimList 中,于是停止工作。因此最终我们得到的 $result 是“ test. ”,而非“ test.r ”。

至于本文开头的例子,当然也是因为这个原因导致的错误了。

<?php
$src = '战争片';
echo rawurlencode($src), "\n";
得到结果:
%E6%88%98
%E4%BA%89%E7%89%87
可见“片”的编码( utf8 )是 E7 89 87 三个字符,因此 trim 工作时,除了去掉了“片”,还将“争”字最后的 89 去掉了!因此,“争”是不完整的, mb_convert_encoding 时被去掉了。

解决:

<?php
$src = '战争片';
$result = preg_replace('/片$/', '', $src);
echo mb_convert_encoding($result, 'gbk', 'utf-8'),"\n";


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值