mb_strpos和strpos有什么区别?

13

是的,我知道。当我们使用多字节字符时,应该使用 mb_* 函数。但是当我们使用 strpos 时呢? 让我们看一下这段代码(保存为 utf-8)。

var_dump(strpos("My symbol utf-8 is the €.", "\xE2\x82\xAC")); // int(23)

使用 mb_strpos 与 strpos 有何区别?它们难道不是完成相同的工作吗? 毕竟,strpos 不就是在查找一个多字节字符串吗?那么为什么要使用 strpos?


1
这可能会有所帮助 :: http://stackoverflow.com/questions/5712226/when-should-i-use-mb-strpos-over-strpos - Sudhir Bastakoti
3个回答

17

对于UTF-8编码,匹配字节序列与匹配字符序列是完全相同的。

因此,它们都将在完全相同的位置找到针,但是mb_strpos会在针前计算完整的UTF-8字节序列,而strpos则计算任何字节。因此,如果您的字符串具有另一个多字节UTF-8序列,则结果将不同:

strpos("My symbolö utf-8 is the €.", "€") !== mb_strpos("My symbolö utf-8 is the €.", "€", 0, "UTF-8")

但是:

strpos("My symbol utf-8 is the €.", "€") === mb_strpos("My symbol utf-8 is the €.", "€", 0, "UTF-8")

8
根据使用的字符集和要搜索的字符串,这可能会或可能不会有所不同。 strpos() 查找作为搜索词传递的字节序列。 mb_strpos() 做同样的事情,但它还尊重字符边界。
因此,strpos() 会在字符串中任何位置匹配字节序列。只有当字节序列表示完整字符集的有效集时,mb_strpos() 才会进行匹配。

这不是真的,mb_strpos() 也会找到无效字符集。唯一的区别在于返回值和参数(字符而不是字节),但无效字符的处理方式是相同的。 - Danon

5

我认为上述例子并不是完全透明的,可能会让一些用户感到困惑。

mb_string() 应该用于多字节编码,而什么是多字节编码,您可以在其他问题中解释,例如 这里

最近我们主要使用 UTF 编码,如本例中的 UTF-8(还有 UTF-16),这是一种多字节字符集,然而通常我们只使用 ASCII 字符集(例如英语),对于它们,strposmb_strpos 的结果是相同的。

差异在于当我们使用多字节字符,即中文字符时可见。

echo mb_internal_encoding(); //UTF-8

echo strpos('我在买绿茶', '在'); //3

echo mb_strpos('我在买绿茶', '在'); //1

显然,这适用于中文字符,但也适用于表情符号,一些人可能不知道。

为了让您更好地了解它的工作方式,我将使用strlen()mb_strlen()函数显示以下字符串的长度。

echo strlen('我在买绿茶'); //15

echo mb_strlen('我在买绿茶'); //5

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接