2012-04-14 155 views
30

我有php文档signup.php,它将form(form.php文档)中的内容保存到MySQL base中。当我想重新格式化输入内容时,问题就出现了。我想要解码UTF-8 charachters像à-> a。PHP替换特殊字符,如à-> a,è-> e

$first_name=$_POST['first_name']; 
    $last_name=$_POST['last_name']; 
    $course=$_POST['course']; 

    $chain="prêt-à-porter"; 

$pattern = array("'é'", "'è'", "'ë'", "'ê'", "'É'", "'È'", "'Ë'", "'Ê'", "'á'", "'à'", "'ä'", "'â'", "'å'", "'Á'", "'À'", "'Ä'", "'Â'", "'Å'", "'ó'", "'ò'", "'ö'", "'ô'", "'Ó'", "'Ò'", "'Ö'", "'Ô'", "'í'", "'ì'", "'ï'", "'î'", "'Í'", "'Ì'", "'Ï'", "'Î'", "'ú'", "'ù'", "'ü'", "'û'", "'Ú'", "'Ù'", "'Ü'", "'Û'", "'ý'", "'ÿ'", "'Ý'", "'ø'", "'Ø'", "'œ'", "'Œ'", "'Æ'", "'ç'", "'Ç'"); 

$replace = array('e', 'e', 'e', 'e', 'E', 'E', 'E', 'E', 'a', 'a', 'a', 'a', 'a', 'A', 'A', 'A', 'A', 'A', 'o', 'o', 'o', 'o', 'O', 'O', 'O', 'O', 'i', 'i', 'i', 'I', 'I', 'I', 'I', 'I', 'u', 'u', 'u', 'u', 'U', 'U', 'U', 'U', 'y', 'y', 'Y', 'o', 'O', 'a', 'A', 'A', 'c', 'C'); 

$chain = preg_replace($pattern, $replace, $chain); 

echo $chain; // print pret-a-porter 

$first_name = preg_replace($pattern, $replace, $first_name); 

echo $first_name; // does not change the input!?! 

为什么它完美的$链,但是对于$ FIRST_NAME或$姓氏不工作?

而且我尝试

echo $first_name; // print áááááábéééééébšššš 
$trans = array("á" => "a", "é" => "e", "š" => "s"); 
echo strtr("áááááábéééééébšššš", $trans); // print aaaaaabeeeeeebssss 
echo strtr($first_name,$trans); // print áááááábéééééébšššš 

但问题,正如你所看到的,是一样的!

+2

请问您的文件有正确的编码? $ _POST中的东西是否具有相同的编码? (即您为浏览器设置的显示页面?)您可能还想设置prec_replace的unicode标志 – phant0m 2012-04-14 10:36:19

+1

正如phant0m所述,您需要密切关注所有编码。使用POST的默认编码是ISO-8859-1,除非您明确地告诉它是您想要的。 (accept-charset ='UTF-8') – dmp 2012-04-14 10:41:12

+0

添加了几个示例函数:) – dmp 2012-04-14 10:58:27

回答

63

有一个更简单的方法来做到这一点,利用iconv - 从用户的笔记,这似乎是你想要做什么:characters transliteration

// PHP.net User notes 
<?php 
    $string = "ʿABBĀSĀBĀD"; 

    echo iconv('UTF-8', 'ISO-8859-1//TRANSLIT', $string); 
    // output: [nothing, and you get a notice] 

    echo iconv('UTF-8', 'ISO-8859-1//IGNORE', $string); 
    // output: ABBSBD 

    echo iconv('UTF-8', 'ISO-8859-1//TRANSLIT//IGNORE', $string); 
    // output: ABBASABAD 
    // Yay! That's what I wanted! 
?> 

很尽责你的字符编码,所以您在过程的所有阶段都保持相同的编码 - 前端,表单提交,源文件的编码。 PHP和表单中的默认编码是ISO-8859-1,在PHP 5.4之前,它更改为UTF8(最后!)。

有几个功能,你可以玩的想法。首先是从CakePHP的变形器类,名为slug

public static function slug($string, $replacement = '_') { 
    $quotedReplacement = preg_quote($replacement, '/'); 

    $merge = array(
     '/[^\s\p{Ll}\p{Lm}\p{Lo}\p{Lt}\p{Lu}\p{Nd}]/mu' => ' ', 
     '/\\s+/' => $replacement, 
     sprintf('/^[%s]+|[%s]+$/', $quotedReplacement, $quotedReplacement) => '', 
    ); 

    $map = self::$_transliteration + $merge; 
    return preg_replace(array_keys($map), array_values($map), $string); 
} 

这取决于一个self::$_transliteration阵列,类似于你在你的问题正在做的事情上 - 你可以see the source for inflector on github

另一个是我个人使用的功能,其中comes from here

function slugify($text,$strict = false) { 
    $text = html_entity_decode($text, ENT_QUOTES, 'UTF-8'); 
    // replace non letter or digits by - 
    $text = preg_replace('~[^\\pL\d.]+~u', '-', $text); 

    // trim 
    $text = trim($text, '-'); 
    setlocale(LC_CTYPE, 'en_GB.utf8'); 
    // 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 'empty_$'; 
    } 
    if ($strict) { 
     $text = str_replace(".", "_", $text); 
    } 
    return $text; 
} 

什么这些功能做的是音译,并从任意的文本输入,这是使Web应用程序时,在你的工具箱中一个非常非常有用的东西创建“slugs”。希望这可以帮助!

+2

谢谢你的回答,问题是我没有在表单中加入“accept-charset =”UTF-8“”。 – 2012-04-14 11:10:11

+0

欢迎,我想所有这些功能都不是真的需要:)但不妨看一看。 – dmp 2012-04-14 11:14:55

+1

我继续使用我的功能,因为有了它,我可以确切地确定用哪个字母来代替某个字母。 – 2012-04-14 14:46:25

5

字符串$ chain与数组中的字符具有相同的字符编码 - 甚至有可能是$ first_name字符串使用不同的编码,所以这些字符不匹配。您可能想尝试使用多字节字符串函数。

尝试mb_convert_encoding。您可能还想尝试使用HTML_ENTITIES作为to_encoding参数,那么您不必担心字符将如何转换 - 这将是非常可预测的。

假设你输入这个脚本是UTF-8,可能不是一个坏的地方开始......

$first_name = mb_convert_encoding($first_name, "HTML-ENTITIES", "UTF-8"); 
+0

我试过了,但事实并非如此。 echo $ first_name; // printááááábéééébšššš $ first_name = mb_convert_encoding($ first_name,“HTML-ENTITIES”,“UTF-8”); echo $ first_name; // printááááábééééébšššš – 2012-04-14 10:58:09

+0

谢谢你的回答,问题在于我没有在表单中添加“accept-charset =”UTF-8“”。 – 2012-04-14 11:10:43

14

这里有一个方法有什么应该被丢弃一些灵活性,应该是什么更换。 这就是我目前的做法。

$ string ='À一些带垃圾的字符串Ĩ';

$replace = [ 
    '&lt;' => '', '&gt;' => '', '&#039;' => '', '&amp;' => '', 
    '&quot;' => '', 'À' => 'A', 'Á' => 'A', 'Â' => 'A', 'Ã' => 'A', 'Ä' => 'Ae', 
    '&Auml;' => 'A', 'Å' => 'A', 'Ā' => 'A', 'Ą' => 'A', 'Ă' => 'A', 'Æ' => 'Ae', 
    'Ç' => 'C', 'Ć' => 'C', 'Č' => 'C', 'Ĉ' => 'C', 'Ċ' => 'C', 'Ď' => 'D', 'Đ' => 'D', 
    'Ð' => 'D', 'È' => 'E', 'É' => 'E', 'Ê' => 'E', 'Ë' => 'E', 'Ē' => 'E', 
    'Ę' => 'E', 'Ě' => 'E', 'Ĕ' => 'E', 'Ė' => 'E', 'Ĝ' => 'G', 'Ğ' => 'G', 
    'Ġ' => 'G', 'Ģ' => 'G', 'Ĥ' => 'H', 'Ħ' => 'H', 'Ì' => 'I', 'Í' => 'I', 
    'Î' => 'I', 'Ï' => 'I', 'Ī' => 'I', 'Ĩ' => 'I', 'Ĭ' => 'I', 'Į' => 'I', 
    'İ' => 'I', 'IJ' => 'IJ', 'Ĵ' => 'J', 'Ķ' => 'K', 'Ł' => 'K', 'Ľ' => 'K', 
    'Ĺ' => 'K', 'Ļ' => 'K', 'Ŀ' => 'K', 'Ñ' => 'N', 'Ń' => 'N', 'Ň' => 'N', 
    'Ņ' => 'N', 'Ŋ' => 'N', 'Ò' => 'O', 'Ó' => 'O', 'Ô' => 'O', 'Õ' => 'O', 
    'Ö' => 'Oe', '&Ouml;' => 'Oe', 'Ø' => 'O', 'Ō' => 'O', 'Ő' => 'O', 'Ŏ' => 'O', 
    'Œ' => 'OE', 'Ŕ' => 'R', 'Ř' => 'R', 'Ŗ' => 'R', 'Ś' => 'S', 'Š' => 'S', 
    'Ş' => 'S', 'Ŝ' => 'S', 'Ș' => 'S', 'Ť' => 'T', 'Ţ' => 'T', 'Ŧ' => 'T', 
    'Ț' => 'T', 'Ù' => 'U', 'Ú' => 'U', 'Û' => 'U', 'Ü' => 'Ue', 'Ū' => 'U', 
    '&Uuml;' => 'Ue', 'Ů' => 'U', 'Ű' => 'U', 'Ŭ' => 'U', 'Ũ' => 'U', 'Ų' => 'U', 
    'Ŵ' => 'W', 'Ý' => 'Y', 'Ŷ' => 'Y', 'Ÿ' => 'Y', 'Ź' => 'Z', 'Ž' => 'Z', 
    'Ż' => 'Z', 'Þ' => 'T', 'à' => 'a', 'á' => 'a', 'â' => 'a', 'ã' => 'a', 
    'ä' => 'ae', '&auml;' => 'ae', 'å' => 'a', 'ā' => 'a', 'ą' => 'a', 'ă' => 'a', 
    'æ' => 'ae', 'ç' => 'c', 'ć' => 'c', 'č' => 'c', 'ĉ' => 'c', 'ċ' => 'c', 
    'ď' => 'd', 'đ' => 'd', 'ð' => 'd', 'è' => 'e', 'é' => 'e', 'ê' => 'e', 
    'ë' => 'e', 'ē' => 'e', 'ę' => 'e', 'ě' => 'e', 'ĕ' => 'e', 'ė' => 'e', 
    'ƒ' => 'f', 'ĝ' => 'g', 'ğ' => 'g', 'ġ' => 'g', 'ģ' => 'g', 'ĥ' => 'h', 
    'ħ' => 'h', 'ì' => 'i', 'í' => 'i', 'î' => 'i', 'ï' => 'i', 'ī' => 'i', 
    'ĩ' => 'i', 'ĭ' => 'i', 'į' => 'i', 'ı' => 'i', 'ij' => 'ij', 'ĵ' => 'j', 
    'ķ' => 'k', 'ĸ' => 'k', 'ł' => 'l', 'ľ' => 'l', 'ĺ' => 'l', 'ļ' => 'l', 
    'ŀ' => 'l', 'ñ' => 'n', 'ń' => 'n', 'ň' => 'n', 'ņ' => 'n', 'ʼn' => 'n', 
    'ŋ' => 'n', 'ò' => 'o', 'ó' => 'o', 'ô' => 'o', 'õ' => 'o', 'ö' => 'oe', 
    '&ouml;' => 'oe', 'ø' => 'o', 'ō' => 'o', 'ő' => 'o', 'ŏ' => 'o', 'œ' => 'oe', 
    'ŕ' => 'r', 'ř' => 'r', 'ŗ' => 'r', 'š' => 's', 'ù' => 'u', 'ú' => 'u', 
    'û' => 'u', 'ü' => 'ue', 'ū' => 'u', '&uuml;' => 'ue', 'ů' => 'u', 'ű' => 'u', 
    'ŭ' => 'u', 'ũ' => 'u', 'ų' => 'u', 'ŵ' => 'w', 'ý' => 'y', 'ÿ' => 'y', 
    'ŷ' => 'y', 'ž' => 'z', 'ż' => 'z', 'ź' => 'z', 'þ' => 't', 'ß' => 'ss', 
    'ſ' => 'ss', 'ый' => 'iy', 'А' => 'A', 'Б' => 'B', 'В' => 'V', 'Г' => 'G', 
    'Д' => 'D', 'Е' => 'E', 'Ё' => 'YO', 'Ж' => 'ZH', 'З' => 'Z', 'И' => 'I', 
    'Й' => 'Y', 'К' => 'K', 'Л' => 'L', 'М' => 'M', 'Н' => 'N', 'О' => 'O', 
    'П' => 'P', 'Р' => 'R', 'С' => 'S', 'Т' => 'T', 'У' => 'U', 'Ф' => 'F', 
    'Х' => 'H', 'Ц' => 'C', 'Ч' => 'CH', 'Ш' => 'SH', 'Щ' => 'SCH', 'Ъ' => '', 
    'Ы' => 'Y', 'Ь' => '', 'Э' => 'E', 'Ю' => 'YU', 'Я' => 'YA', 'а' => 'a', 
    'б' => 'b', 'в' => 'v', 'г' => 'g', 'д' => 'd', 'е' => 'e', 'ё' => 'yo', 
    'ж' => 'zh', 'з' => 'z', 'и' => 'i', 'й' => 'y', 'к' => 'k', 'л' => 'l', 
    'м' => 'm', 'н' => 'n', 'о' => 'o', 'п' => 'p', 'р' => 'r', 'с' => 's', 
    'т' => 't', 'у' => 'u', 'ф' => 'f', 'х' => 'h', 'ц' => 'c', 'ч' => 'ch', 
    'ш' => 'sh', 'щ' => 'sch', 'ъ' => '', 'ы' => 'y', 'ь' => '', 'э' => 'e', 
    'ю' => 'yu', 'я' => 'ya' 
]; 

echo str_replace(array_keys($replace), $replace, $string); 
3

愿望,我发现这个线程越快。(我花了太长时间)我做了功能如下:

function CheckLetters($field){ 
    $letters = [ 
     0 => "a à á â ä æ ã å ā", 
     1 => "c ç ć č", 
     2 => "e é è ê ë ę ė ē", 
     3 => "i ī į í ì ï î", 
     4 => "l ł", 
     5 => "n ñ ń", 
     6 => "o ō ø œ õ ó ò ö ô", 
     7 => "s ß ś š", 
     8 => "u ū ú ù ü û", 
     9 => "w ŵ", 
     10 => "y ŷ ÿ", 
     11 => "z ź ž ż", 
    ]; 
    foreach ($letters as &$values){ 
     $newValue = substr($values, 0, 1); 
     $values = substr($values, 2, strlen($values)); 
     $values = explode(" ", $values); 
     foreach ($values as &$oldValue){ 
      while (strpos($field,$oldValue) !== false){ 
       $field = preg_replace("/" . $oldValue . '/', $newValue, $field, 1); 
      } 
     } 
    } 
    return $field; 
} 
+1

这是一段天才代码。尤其适用于搜索数据不一致的数据库。我用它来搜索充满用户提供的数据的国家数据库。这确实有助于不添加错误编写的用户内容。一个大拇指从我身上。 – 2016-11-09 22:15:11

+0

感谢您的反馈。不正确地输入用户内容正是为什么写这个:) – ChickenFeet 2016-11-18 07:56:56

+0

只是一个旁注,在功能开始时额外的起始花括号应该明显地被删除 – 2017-07-26 16:22:23

1

笨方法:

$this->load->helper('text'); 

$string = convert_accented_characters($string); 

此功能使用一个同伴配置文件application/config/foreign_chars.php来定义,并从阵列音译。

https://www.codeigniter.com/user_guide/helpers/text_helper.html#ascii_to_entities

+1

1- 2年前提出的问题2-问题有一个可接受的答案。 3 OP没有提及_CI Framework_并且正在使用_plain php_,所以你的回答与这个问题无关。请在发布答案之前多加注意问题 – EhsanT 2016-11-19 05:08:23

+0

经过一天的沮丧之后,这对我有所帮助..对于Codeigniter – 2017-06-20 06:20:24

4

自PHP> = 5.4.0

$translatedString = transliterator_transliterate('Any-Latin; Latin-ASCII; [\u0080-\u7fff] remove', $string); 
+0

真的是一个很好的答案,就像一个魅力 – brnmonteiro 2017-05-09 20:48:46