特别的?哦 字符破坏UTF-8编码

Cor*_*ian 3 php encoding utf-8

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

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

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

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

处理这些字符的最佳方法是什么?我应该尝试替换特殊的吗?哦 字符并将其替换为常规字符,或者我能以某种方式捕获损坏的UTF-8字符并删除或替换它们吗?

IMS*_*SoP 5

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

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

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

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

  • U + 0308“合并诊断”

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

如您所见,这意味着可以用两种不同的方式来表示同一字母。为了解决这个问题,Unicode包括在Unicode标准的附件中定义的 “规范化形式” :

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

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

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

因此,一种可能性是将您的输入转换为NFC,在PHP中可以使用extension中Normalizerintl来实现。

但是,并非所有组合都可以标准化为没有单独变音符号的形式,因此这不能解决您的所有问题。您还可能需要通过匹配Unicode字符属性来查看您确切希望允许的字符

您可能还想了解“字形集群”并使用相关的PHP函数。大多数读者将“字素簇”或仅仅是“字素”视为“一个字符”,例如带有所有变音符号的字母或完整的表意文字。