PHP:是否可以正确地 SUBSTR UTF-8 字符串?

PHP: Is it possible to correctly SUBSTR a UTF-8 string?

提问人:texnic 提问时间:9/16/2012 最后编辑:Communitytexnic 更新时间:11/2/2018 访问量:27729

问:

我有(在SQLite数据库中)以下字符串:

Лампа в вытяжке на кухне меняется, начиная с вытаскивания белого штырька справа.

PHP 使用 正确显示该字符串。我只想获得这个字符串的前 50 个字符,即print

Лампа в вытяжке на кухне меняется, начиная с вытас.

我尝试同时使用 substr 和 mb_substr,然后得到

Лампа в вытяжке на кухне ме�,即只有 28 个字符。

在阅读了这里和其他地方关于 mbstring 的问题后,我意识到这实际上是一个 50 字节的字符串(22 个俄语字符 = 44 个字节加上 5 个空格和 1 个问题符号)。

有什么好的解决方案吗?我所有的字符串都是 UTF-8,所以我当然可以自己编写一个子函数,通过检查每个字节的第一位等。但这肯定应该以前做过,对吧?

更新:我相信不能正常工作,因为不能正常工作mb_substrmb_detect_encoding()

PHP 编码 UTF-8 子字符串

评论

10赞 h2ooooooo 9/16/2012
你说你已经尝试过了,但你有没有尝试过指定编码?例如,有效吗?mb_substrmb_substr($string, 0, 10, "UTF-8")
5赞 DCoder 9/16/2012
确保将正确的编码传递给 - 对我有用,不对。mb_substrmb_substr($input, 0, 50, 'UTF-8')mb_substr($input, 0, 50)
0赞 texnic 9/16/2012
@h2ooooooo:我没有,我在手册中错过了。确实如此。请添加您的评论作为答案,我会接受的。
0赞 h2ooooooo 9/16/2012
@texnic 别担心,你应该接受 Abid 的回答,因为这似乎对将来寻找这个问题的人更具描述性和有用性。

答:

9赞 texnic 9/16/2012 #1

像往常一样,答案似乎就在这里。(老实说,我已经搜索了大约一个小时)

在 php 中,(鉑)字符串函数和 UTF8 的答案如下:

确保设置了正确的内部编码:mb_internal_encoding('utf-8');

有了这个mb_internal_encoding('utf-8'); 一切正常。很抱歉打扰你们,感谢您的帮助。

评论

3赞 h2ooooooo 9/16/2012
正如我在 OP 上的评论中提到的,我相信这也会奏效,但我很高兴你找到了你的解决方案(嘿,如果你使用很多不同的地方,这是一个更好的解决方案!mb_substr($string, 0, 50, "UTF-8")mb_substr
25赞 Abid Hussain 9/16/2012 #2

请参阅下面的 URL:

在 PHP 中从 UTF-8 字符串中提取子字符串

http://osc.co.cr/extracting-a-substring-from-a-utf-8-string-in-php/

带有 UTF-8 的 PHP 子字符串

http://greekgeekz.blogspot.in/2010/11/php-substring-with-utf-8.html

或者试试看:

示例#1

$str1 = utf8_encode("Feliz día");

$str2 = substr($str1, 0, 9);

echo utf8_decode($str2); 

// will output Feliz d�

示例#2

$str3 = mb_substr($str1, 0, 9, 'UTF-8');

echo utf8_decode($str3); 

// will output Feliz dí

从 PHP >= 5.3 开始,您还可以声明编码指令并使用 substr 函数

示例#3

declare(encoding='UTF-8');

$str4 = "Feliz día";

$str5 = substr($str4, 0, 9);echo $str5;


// will output Feliz dí

评论

3赞 texnic 9/16/2012
虽然一切正常,但我最喜欢示例 #3:最好使用单个函数。然而,manual 说:“除非 php 是用 --enable-zend-multibyte 编译的,否则在 PHP 5.3 中会忽略编码声明值。请注意,PHP 不会公开 --enable-zend-multibyte 是否用于编译 phpinfo() 以外的 php。我相信,我现在会坚持mb_功能。declare
14赞 Slavik Meltser 6/9/2016 #3

试试 mb_strcut()。
它的行为与 相同,只是它不会让最后一个字符被破坏。
如果在您尝试剪切的位置,有一个具有 2 个或更多字节的多字节字符,则不会将该字符切成碎片,而是会忽略此字符。
substr()mb_strcut()

例如,如果您尝试从字符串中剪掉 50 个字节,则不会将字符切成两半,而是将其从结果中删除。Лампа в вытяжке на кухне меняется, начиная с вытаскивания белого штырька справа.mb_strcut()н

$str = "Лампа в вытяжке на кухне меняется, начиная с вытаскивания белого штырька справа.";

echo mb_strcut($str, 0, 50);
// Prints: Лампа в вытяжке на кухне ме

echo substr($str, 0, 50);
// Prints: Лампа в вытяжке на кухне ме�

echo mb_substr($str, 0, 50);
// Prints: Лампа в вытяжке на кухне меняется, начиная с вытас

希望它有所帮助。