utf 8 - PHP: strpos & substr with UTF-8


utf 8 - PHP: strpos & substr with UTF-8

假设我有一个UTF-8编码的长字符串。

然后说我想检测这个字符串中是否存在$var

假设$var总是简单的字母或ascii字符的数字(例如"hello123"),我不应该使用mb_strposiconv_strpos,对吗?因为只要位置与其他函数一致,那么位置是否在字符方面不正确也没关系。

示例:

$var='hello123';
$pos=strpos($utf8string,$var);
if ($pos!==false) $uptohere=substr($ut8string,0,$pos);

不管字符串是否包含花哨的UTF-8字符,上面的代码都会提取到'hello123'之前的所有内容,我说得对吗?我的逻辑是,因为strpossubstr将彼此一致(即使这一直是错误的),所以它应该仍然有效。

是的,你是对的。字符本身没有歧义,即hello123在UTF-8中不可能有任何其他内容。切片的方式,无论是按字符还是按字节数进行切片都无关紧要。

因此,是的,这是安全的,只要您的字符串是UTF-8,从而兼容ASCII

请参阅此处进行快速测试:http://3v4l.org/XnM8s

为什么这样做:

字符串"漢字hello123"在UTF-8中看起来像字节(我希望它正确对齐):

e6 | bc | a2 | e5 | ad | 97 | 68 | 65 | 6c | 6c | 6f | 31 | 32 | 33
     漢      |      字      | h  | e  | l  | l  | o  | 1  | 2  | 3

strpos将查找字节序列68656c6c6f313233,返回6作为"hello123"的起始字节。substr将从字节0中截取6个字节,返回"漢字".没有歧义。你是按字节查找和切片的,有多少字符并不重要。

您需要完全使用字符,在这种情况下,字符串函数必须具有编码意识。或者您完全在字节中工作,在这种情况下,唯一的要求是字节不含糊(比如"hello123"可以匹配中国"在BIG5中编码,因为字节是相同的(它们不一样,只是一个例子)。UTF-8是自同步,这意味着没有这种模糊性。

在UTF-8中,您必须使用mb_*函数,在这种情况下,您需要将substr替换为

mb_substr($var, 0, N, 'UTF-8');

mb_substr()