特殊的aoö字符会破坏UTF-8编码

时间:2019-02-28 13:22:31

标签: php encoding utf-8

我网站上的用户在文本字段中输入了特殊字符:äö

这些显然不是我可以从键盘输入的äö字符,因为当我将它们粘贴到程序员的记事本中时,它们分成了两个部分:a o o

在我网站的服务器端,我有一个PHP脚本,该脚本可识别用户输入中的非法特殊字符,并在带有preg_replace的html错误消息中将其高亮显示。

那里也发生字符拆分,因此我得到一个普通的字母a和o,以及一个奇怪的xCC奇怪字符,它破坏了UTF-8字符串编码,结果json_encode函数失败了。

处理这些字符的最佳方法是什么?我应该尝试替换特殊的aoö字符并用常规的替换吗,还是可以以某种方式捕获损坏的UTF-8字符并删除或替换呢?

1 个答案:

答案 0 :(得分:4)

不是这些字符破坏了编码,只是 Unicode确实很复杂

常用的带重音的字母在Unicode标准中具有自己的代码点,在这种情况下:

  • U + 00E4“带有小写字母的拉丁文小写字母A”
  • U + 00F6“带有小写字母的拉丁文小写字母O”

但是,为避免对所有可能性进行编码,尤其是当需要在同一字母上放置多个变音符号时,Unicode包括“组合变音符号”,例如:

  • U + 0308“合并诊断”

当放置在普通字母的代码点之后时,这些代码点在显示时会为其添加变音符号

如您所见,这意味着有两种不同的方式表示同一字母。为了解决这个问题,Unicode包含“规范化表单” defined in an annex to the Unicode standard

  • 归一化表格D(NFD):规范分解
  • 规范化形式C(NFC):规范分解,然后是规范组合
  • 归一化表格KD(NFKD):兼容性分解
  • 归一化形式KC(NFKC):兼容性分解,然后按规范组合

暂时忽略“兼容性”表格,我们有两个选择:

  • 分解,它尽可能多地使用变音符号组合
  • 组成,它会尽可能频繁地使用特定的代码点

因此,一种可能性是将您的输入转换为NFC,这可以通过the Normalizer class in the intl extension在PHP中实现。

但是,并非所有组合都可以规范化为没有单独的变音符号的形式,因此这不能解决您的所有问题。您还需要查看可能要使用的字符,大概是matching Unicode character properties

您可能还想了解“字素簇”并使用the relevant PHP functions。大多数读者会认为“字素簇”,或者仅仅是“字素”,例如带有所有变音符号的字母或完整的表意文字。