带有 utf-8 的 php substr() 函数在末尾留下 � 标记

Posted

技术标签:

【中文标题】带有 utf-8 的 php substr() 函数在末尾留下 � 标记【英文标题】:php substr() function with utf-8 leaves � marks at the end 【发布时间】:2012-02-23 15:24:28 【问题描述】:

这里是简单的代码

<?php

$var = "Бензин Офиси А.С. также производит все типы жира и смазок и их побочных        продуктов в его смесительных установках нефти машинного масла в Деринце, Измите, Алиага и Измире. У Компании есть 3 885 станций технического обслуживания, включая сжиженный газ (ЛПГ) станции под фирменным знаком Петрогаз, приблизительно 5 000 дилеров, двух смазочных смесительных установок, 12 терминалов, и 26 единиц поставки аэропорта.";

$foo = substr($var,0,142);

echo $foo;
?>

它会输出如下内容:

Бензин Офиси А.С。 также производит все типы жира и смазок и их побочных продук...

我尝试了 mb_substr(),但没有成功。如何以正确的方式做到这一点?

【问题讨论】:

mb_substr() 是可行的方法,当多字节字符被切成两半时会发生这种情况。你能展示一下你尝试了什么以及它是如何失败的吗? 您在尝试mb_substr时是否指定了编码(最后一个参数)? 这正是我试图做的。我没有在互联网上,所以我不能提供链接。它是对公司的详细描述,我将其剪裁为 142 个字符,以显示在一个网站的主页上。 @JohnFlatness 不,我没有指定,我只是用 mb_substr() 替换了 substr()。让我检查一下 好的,非常感谢!我没有指定 mb_substr() 函数的最后一个参数,即 @JohnFlatness 指出的“UTF-8”。现在一切都很好!非常感谢你们! 【参考方案1】:

永远不要在substr 函数中为UTF-8 字符串使用常量:

$st = substr($text, $beg, 100);

50% 的几率你会在字符串末尾获得一半的字符。

这样做:

$postion_degin = strpos($text, $first_symbol);
$postion_end = strpos($text, $last_symbol);
$len = $postion_end - $postion_degin + 1;
$st = substr($text, $postion_degin, $len);

100% 安全的结果。

没有mb_substr

【讨论】:

如果您知道要剪切哪些字符,那就太好了。如果你只想拥有一个随机字符串的前 3 个字符,那就不好了。正确的方法是使用 mb_substr。【参考方案2】:

如果你想使用strlen函数来计算你想要返回的字符串的长度并且你的字符串$wordUTF-8编码,你必须使用mb_strlen()函数:

$foo = mb_substr($word, 0, mb_strlen($word)-1);

【讨论】:

完美地工作mb_substr。我试过substr 不工作:)【参考方案3】:

如果您的字符串可能包含 Unicode(多字节)字符并且您不想破坏这些字符,请将 substr 替换为以下两个之一,具体取决于您的需要:

限制为 142 个字符

mb_substr($var, 0, 142);

限制为 142 字节

mb_strcut($var, 0, 142);

【讨论】:

【参考方案4】:

我希望这个解决方案对你有帮助,因为它对我有很大帮助。

<?php
if(mb_strlen($post->post_content,'UTF-8')>200)
    $content= str_replace('\n', '', mb_substr(strip_tags($post-> post_content), 
                          0, 200,'UTF-8'));
    echo $content.'…';
else
    echo str_replace('\n', '', strip_tags($post->post_content));

?>

【讨论】:

【参考方案5】:

unicode 字符串的适当(逻辑)替代方案;

<?php
function substr_unicode($str, $s, $l = null) 
    return join("", array_slice(
        preg_split("//u", $str, -1, PREG_SPLIT_NO_EMPTY), $s, $l));


$str = "Büyük";
$s = 0; // start from "0" (nth) char
$l = 3; // get "3" chars
echo substr($str, $s, $l) ."\n";    // Bü
echo mb_substr($str, $s, $l) ."\n"; // Bü
echo substr_unicode($str, $s, $l);  // Büy
?>

使用PHP: mb_substr - Manual

【讨论】:

mb_substr($str, $s, $l, 'UTF-8') 是真正合适的选择......!如果没有正确指定的字符集,结果是什么。 在 PHP 5.6 中这是唯一可行的选择。谢谢!【参考方案6】:

只要您在服务器上启用了 mbstring,上述 cmets 都是正确的。

$var = "Бензин Офиси А.С. также производит все типы жира и смазок и их побочных        продуктов в его смесительных установках нефти машинного масла в Деринце, Измите, Алиага и Измире. У Компании есть 3 885 станций технического обслуживания, включая сжиженный газ (ЛПГ) станции под фирменным знаком Петрогаз, приблизительно 5 000 дилеров, двух смазочных смесительных установок, 12 терминалов, и 26 единиц поставки аэропорта.";

$foo = mb_substr($var,0,142, "utf-8");

这是 php 文档:

http://php.net/manual/en/book.mbstring.php

【讨论】:

谢谢!我错过的最后一个参数是“UTF-8”,但我查看了文档。【参考方案7】:

PHP5 本身不理解 UTF-8。它是为 PHP6 提出的,如果它出现的话。

使用multibyte string functions 安全地操作UTF-8 字符串。

例如,mb_substr() 在您的情况下。

【讨论】:

事实证明他们跳过了 PHP 6 直接进入了 PHP 7。仍然没有原生 unicode 支持。 Perl 至少从 Perl 5.6 开始就有它。

以上是关于带有 utf-8 的 php substr() 函数在末尾留下 � 标记的主要内容,如果未能解决你的问题,请参考以下文章

php去掉文件UTF-8的BOM头

PHP用*隐藏中文问题

php截取utf-8中文字符串乱码的解决方法

php截取中文字符串无乱码的方法

[单选题]以下程序运行的结果是: <?php $str="明日编程词典"; echo substr_count($str,"词");?>

PHP 发送带有自定义和回复的UTF-8编码邮件