php iconv translit删除重音:不能作为例外工作?

时间:2011-02-06 00:14:15

标签: php string unicode utf-8 unicode-normalization

考虑这个简单的代码:

echo iconv('UTF-8', 'ASCII//TRANSLIT', 'è');

打印

 `e

而不仅仅是

 e
你知道我做错了吗?


添加setlocale

后,

没有任何变化

setlocale(LC_COLLATE, 'en_US.utf8');
echo iconv('UTF-8', 'ASCII//TRANSLIT', 'è');

7 个答案:

答案 0 :(得分:9)

我有这个标准函数来返回没有无效url字符的有效url字符串。在 //删除不需要的字符评论后,神奇似乎就在了一线。

这取自Symfony框架文档:http://www.symfony-project.org/jobeet/1_4/Doctrine/en/08,后者取自http://php.vrana.cz/vytvoreni-pratelskeho-url.php,但我不会说捷克语; - )

function slugify($text)
{
  // replace non letter or digits by -
  $text = preg_replace('#[^\\pL\d]+#u', '-', $text);

  // trim
  $text = trim($text, '-');

  // transliterate
  if (function_exists('iconv'))
  {
    $text = iconv('utf-8', 'us-ascii//TRANSLIT', $text);
  }

  // lowercase
  $text = strtolower($text);

  // remove unwanted characters
  $text = preg_replace('#[^-\w]+#', '', $text);

  if (empty($text))
  {
    return 'n-a';
  }

  return $text;
}

echo slugify('é'); // --> "e"

答案 1 :(得分:6)

cf @tchrist,使用INTL php扩展

http://fr2.php.net/manual/en/book.intl.php

preg_replace('/\pM*/u','',normalizer_normalize( $mystring, Normalizer::FORM_D));

eéèêëiîïoöôuùûüaâäÅἭŐǟǠǺƶƈƉųŪŧȬƀ␢ĦȽŦȽŦƀǖ成为

eeeeeiiiooouuuuaaaΗOAAAƶƈƉuUŧOƀ␢ĦŁȽŦȽŦu


正如tchrist强调的那样,并非所有unicode字符都被认为是可分解的:

从Unicode图表中提取:

U0080.pdf

  <00> 00CF我带有DIAERESIS的LATIN CAPITAL LETTER

     

≡0049I0308¨

     

注意这个符号«≡»表示可用的分解

     <00> 00D0 - 拉丁文大写字母ETH

     

→00F0ð拉丁小写字母

     

→0110©拉丁语大写字母d中风

     

→0189Ɖ拉丁语大写字母非洲d

没有可用的分解,恕我直言(我们可以将ASCII字母D视为可接受的等效物)。

U0100.pdf

  

0110©LATIN CAPITAL LETTER D WITH STROKE

     

→00D0 - 拉丁语大写字母eth

     

→0111đ拉丁小写字母d中风

     

→0189Ɖ拉丁语大写字母非洲d

甚至更奇怪:这个被识别为LATIN CAPITAL LETTER D(中风),但不能分解!也许更酷的解决方案应该是获取每个char的unicode描述,并将其与每个ascii char的描述进行比较(并相应地替换)。任何人? ; - ]

cf http://unicode.org/Public/UNIDATA/UnicodeData.txt

答案 2 :(得分:2)

我发现没有php的纯iconv。诀窍是将LANG环境值设置为en_US.UTF-8(在我的情况下,它之前是hu_HU.UTF-8)。在按预期工作后。

答案 3 :(得分:0)

在进行音译时,您必须确保正确设置了LC_COLLATE,否则将使用默认的POSIX。

查看http://uk3.php.net/manual/en/function.setlocale.php

答案 4 :(得分:0)

我很想说“没事”,虽然这有点超出我的专业水平。 PHP的iconv()是臭名昭着的,也是许多解决方法的灵感来源,包括

  • 放入系统的iconv 实用程序(Unix和Linux)
  • 制作查找表
  • 替换所有重音字符 使用ASCII等价物作为一种 预处理阶段
  • 设置LC_COLLATE(没有 似乎适合所有人)
  • 使用htmlentities()而不是iconv()

阅读iconv() documentation的评论,获取更多灵感。 (或者同情。太接近电话了。)

答案 5 :(得分:0)

似乎处理此问题的标准方法是使用“删除重音符号”功能,您可以在flourish等库或Wordpress之类的CMS中找到它。 Iconv似乎无法翻译口音(这是正确的),因为除了URL slugs之外,这不是一个好主意。

答案 6 :(得分:-1)

它似乎取决于php版本......

TestCase#1

php -version

PHP 7.0.0RC8 (cli)(建于2015年11月25日12:36:50)(NTS) 版权所有(c)1997-2015 PHP小组 Zend Engine v3.0.0,版权所有(c)1998-2015 Zend Technologies     Zend Technologies的Zend OPcache v7.0.6-dev,Copyright(c)1999-2015,

php -r "var_dump(iconv('UTF-8', 'ASCII//TRANSLIT', 'è'));"

string(2) "`e"

TestCase#2

php -version

PHP 7.0.8-1~docdeb + 8.1 (cli)(NTS) 版权所有(c)1997-2016 PHP小组 Zend Engine v3.0.0,版权所有(c)1998-2016 Zend Technologies     与Zend OPcache v7.0.8-1~dotdeb + 8.1,版权所有(c)1999-2016,作者:Zend Technologies

php -r "var_dump(iconv('UTF-8', 'ASCII//TRANSLIT', 'è'));"

string(1) "e"
相关问题