在PHP中剪切一个UTF8文本

问题描述:

我从数据库中获取UTF8文本,并且只想显示前面的$ len个字符(以单词形式完成)。我已经尝试了几个选项,但由于特殊字符(á,é,í,ó等),该功能仍然不起作用。在PHP中剪切一个UTF8文本

感谢您的帮助!

function text_limit($text, $len, $end='...') 
{ 

    mb_internal_encoding('UTF-8'); 
    if((mb_strlen($text, 'UTF-8') > $len)) { 

    $text = mb_substr($text, 0, $len, 'UTF-8'); 
    $text = mb_substr($text, 0, mb_strrpos($text," ", 'UTF-8'), 'UTF-8'); 

    ... 
    } 
} 

编辑。如果我截断文本有65个字符添加一个例子

,它返回:

的Un哈尔丁ESTILOneoclásicoacorde CON EL ...

如果我更改特殊字符(í,á),则返回:

的Un哈尔丁ESTILO neoclasico acorde CON EL宫...

我敢肯定有一些奇怪的事情与编码或服务器或PHP;但我无法弄清楚!谢谢!

最终解决

我使用这个UTF8 PHP library,一切工作现在...

+0

如果你不使用text_limit,那么编码不会产生问题,对吧? – 2010-07-20 21:37:58

+0

显示的文字没有任何问题。问题出在我剪切它时,那些特殊字符占用几个字节,所以text_limit()返回一个非常短的字符串。 – fesja 2010-07-20 21:53:50

+0

[将多字节字符串截断为n个字符](http://*.com/questions/2154220/truncate-a-multibyte-string-to-n-chars) – Gordon 2010-07-20 22:01:05

使用mb_substr。首先检查第二个字符串是起始位置,第三个是长度,最后是编码。

mb_substr ("String", 0, $len, 'utf-8'); 
+0

这会返回Str if $ len wa s 3 – 2010-07-20 21:44:25

+0

mmm我已经在使用该功能... – fesja 2010-07-20 21:58:14

+0

woops,对不起,快速查看它,只看到strlen。 – 2010-07-21 21:12:55

mb_strrpos($text," ", 'UTF-8') 

你没有经过足够的参数传递给mb_strrpos()(你省略了偏移 - 第三个参数,编码是4 PARAM),尝试:

mb_strrpos($text," ", 0, 'UTF-8') 

虽然与2号线省略它,它看起来很好,就像你说的那样...“我只想显示第一个$ len字符(整理成一个单词)” - 第二行确保它完成整个单词?

编辑:mb_substr()应削减在$len字符数,而不是字节数。你确定原始文本实际上是UTF-8,而不是其他编码?

+0

感谢有关更正,但它不起作用。第二行删除最后一个不完整的单词(它搜索空间,并将文本剪切到该位置)。 – fesja 2010-07-20 21:56:24

+0

我正在使用'mb_check_encoding($ string,'UTF-8');'检查该字符串是否具有UTF8编码。我的数据库是UTF8,我的symfony系统有UTF8,因为它是默认的字符集。任何想要检查什么?谢谢! – fesja 2010-07-21 08:29:48

如何尝试mb_strcut()。与mb_substr()相同的参数。

好的,所以这让我感到莫名其妙,你无法得到这个工作,因为它应该工作得很好。最后,我想我已经想出了这不适合你的原因。

我认为这里发生的事情是您的浏览器显示错误的编码,并且您正在输出utf-8字符。

你有几个选项。首先,如果您将任何这些内容显示为html页面的一部分,请检查您的元标记以查看它们是否正在设置字符编码。如果是的话就改成这样:

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 

下一个,如果你只是输出这个直接向浏览器中使用标头函数来设置字符编码,像这样:

header("Content-type: text/html; charset=utf-8"); 

一个简单的测试:

<?php 
    header("Content-type: text/html; charset=utf-8"); 
    $text = "áéíó"; 
    echo mb_substr($text, 0, 3, 'utf-8'); 
?> 

没有这你的浏览器将默认为另一种编码,并显示文本不当。希望这可以帮助你解决这个问题,如果不是,我会继续尝试:)

+0

OP表示在使用函数text_limit之前,输出没有问题。因此元标记被IMO设置为UTF-8。顺便说一句:尝试使用编辑,而不是添加新的和新的答案;-) – 2010-07-21 22:17:04

+0

非常感谢凯利,但这不是问题,正如MartyIX所说。 解决方案:使用下面的UTF8库,它现在就可以工作,不要问我为什么 http://tarski.googlecode.com/svn/branches/1.6/library/feedparser/lib-utf8.php – fesja 2010-07-22 09:39:07

这可能是因为你的原始解决方案将字符串截断为65个字节,通常等于65个字符在仅ASCII的上下文中,但在使用UTF-8的多字节范围时变得不正确。将字符串截断为65 字节 - 根据每个字符中的字节数,字符串本身的长度可能是可变的。这也可能是危险的,因为你可以削减一半的字符(拆分多个字节)。