使用 PHP 转换所有类型的智能引号
phpserver side programmingprogramming
可以使用下面的代码行,其中需要 UTF-8 输入。
$chr_map = array( // Windows 代码页 1252 "\xC2\x82" => "'", // U+0082⇒U+201A 单低 9 引号 "\xC2\x84" => '"', // U+0084⇒U+201E 双低 9 引号 "\xC2\x8B" => "'", // U+008B⇒U+2039 单左尖角引号 "\xC2\x91" => "'", // U+0091⇒U+2018 左单引号 "\xC2\x92" => "'", // U+0092⇒U+2019 右单引号 "\xC2\x93" => '"', // U+0093⇒U+201C 左双引号 "\xC2\x94" => '"', // U+0094⇒U+201D 右双引号 "\xC2\x9B" => "'", // U+009B⇒U+203A 单右尖角引号 // 常规 Unicode // U+0022 引号 (") // U+0027 撇号 (') "\xC2\xAB" => '"', // U+00AB 左双角引号 "\xC2\xBB" => '"', // U+00BB 右双角引号 "\xE2\x80\x98" => "'", // U+2018 左单引号 "\xE2\x80\x99" => "'", // U+2019 右单引号 "\xE2\x80\x9A" => "'", // U+201A 单低 9 引号 "\xE2\x80\x9B" => "'", // U+201B 单高反 9 引号 "\xE2\x80\x9C" => '"', // U+201C 左双引号 "\xE2\x80\x9D" => '"', // U+201D 右双引号 "\xE2\x80\x9E" => '"', // U+201E 双低 9 引号 "\xE2\x80\x9F" => '"', // U+201F 双高反 9 引号 "\xE2\x80\xB9" => "'", // U+2039 单左指向角引号 "\xE2\x80\xBA" => "'", // U+203A 单右指向角引号 ); $char_val = array_keys ($chr_map); // 但是:为了提高效率,你应该 $rpl = array_values($chr_map); // 预先计算这两个数组 $str = str_replace($char_val, $rpl, html_entity_decode($str, ENT_QUOTES, "UTF-8"));
解释
每个 unicode 字符都只属于一个"通用类别"。
其中,可以包含引号字符的是 −
Ps "标点符号,打开" Pe "标点符号,关闭" Pi "标点符号,初始引号(根据其用法,可能表现为 Ps 或 Pe)" Pf "标点符号,最终引号(根据其用法,可能表现为 Ps 或 Pe)" Po "标点符号,其他"
如果用户不确定输入是否为 UTF-8 编码,可以在执行其他操作之前放置以下代码 −
if ( !preg_match('/^\X*$/u', $str)) { $str = utf8_encode($str); }
如果数据需要在 0x80-0x9F 范围内规范化,可以使用以下代码 −
$normalization_map = array( "\xC2\x80" => "\xE2\x82\xAC", // U+20AC 欧元符号 "\xC2\x82" => "\xE2\x80\x9A", // U+201A 单个低 9 引号 "\xC2\x83" => "\xC6\x92", // U+0192 带钩的拉丁小写字母 f "\xC2\x84" => "\xE2\x80\x9E", // U+201E 双低 9 引号 "\xC2\x85" => "\xE2\x80\xA6", // U+2026 水平省略号 "\xC2\x86" => "\xE2\x80\xA0", // U+2020 匕首 "\xC2\x87" => "\xE2\x80\xA1", // U+2021 双匕首 "\xC2\x88" => "\xCB\x86", // U+02C6 修饰字母抑扬符 "\xC2\x89" => "\xE2\x80\xB0", // U+2030 千分符号 "\xC2\x8A" => "\xC5\xA0", // U+0160 带抑扬符的拉丁大写字母 s "\xC2\x8B" => "\xE2\x80\xB9", // U+2039 单左尖引号 "\xC2\x8C" => "\xC5\x92", // U+0152 拉丁大写连字 oe "\xC2\x8E" => "\xC5\xBD", // U+017D 带减号的拉丁大写字母 z "\xC2\x91" => "\xE2\x80\x98", // U+2018 左单引号 "\xC2\x92" => "\xE2\x80\x99", // U+2019 右单引号 "\xC2\x93" => "\xE2\x80\x9C", // U+201C 左双引号 "\xC2\x94" => "\xE2\x80\x9D", // U+201D 右双引号 "\xC2\x95" => "\xE2\x80\xA2", // U+2022 项目符号 "\xC2\x96" => "\xE2\x80\x93", // U+2013 短划线 "\xC2\x97" => "\xE2\x80\x94", // U+2014 长划线 "\xC2\x98" => "\xCB\x9C", // U+02DC 小波浪符号 "\xC2\x99" => "\xE2\x84\xA2", // U+2122 商标符号 "\xC2\x9A" => "\xC5\xA1", // U+0161 带减号的拉丁小写字母 s "\xC2\x9B" => "\xE2\x80\xBA", // U+203A 单右指角引号 "\xC2\x9C" => "\xC5\x93", // U+0153 拉丁小连字 oe "\xC2\x9E" => "\xC5\xBE", // U+017E 带减号的拉丁小写字母 z "\xC2\x9F" => "\xC5\xB8", // U+0178 带分音符的拉丁大写字母 y ); $chr = array_keys ($normalization_map); // 但是:为了提高效率,你应该 $rpl = array_values($normalization_map); // 预先计算这两个数组 $str = str_replace($chr, $rpl, $str);