9

在我们的网站上,一些 Mac 用户在将文本从 PDF 文件复制粘贴到 TextArea(由 TinyMCE 处理)时遇到问题。所有重读字符都已损坏,例如变成e?a éi?aî等。我无法在 Windows 计算机上重现此问题。

当我将 TextArea 的内容写入文件时(在将其插入数据库之前),我刚刚发现首字母在视觉上与传统的不同é(在 Vim 上,见下文)。

问题的视觉示例

确实 :

// the corrupted é - first line of the screenshot
echo bin2hex($char); // display 65cc81

// traditionnal é
echo bin2hex('é');   // display c3a9

经过大量搜索,我在这里:Mac OS 似乎将 Unicode 重音字符复制为两个字符的组合:在我们的示例中,e + ́. 到目前为止,我还没有找到任何解决方案来用é真实的替换损坏的,以避免e?在数据库中。

我有点绝望。

4

3 回答 3

8

表示规范化为一种或另一种形式的过程称为规范化。在 PHP 中有这样的Normalizer,通过它发送所有输入是个好主意:

$input = Normalizer::normalize($input);

您可能想要规范化以形成 C,规范分解,然后是规范组合。

如果该类在您的系统上不可用,则可以使用Patchwork UTF-8 library

于 2012-11-27T14:17:42.023 回答
4

这只是@deceze 已经回答的内容的补充。Unicode 中有多种方法可以指定相同的(在等价意义上)字符。

你有一个常见的例子:

65cc81

这是 Utf-8 编码中的两个 Unicode 代码点。 65e 拉丁小写字母 E (U+0065) 并且cc81́ COMBINING ACUTE ACCENT (U+0301) (它不能由您的浏览器单独显示,所以我取了 HTML 实体)。

在 Unicode 中,这称为组合序列。但是由于某种原因,您的数据库不支持它。可能是因为列的编码不是 UTF-8 或者数据库连接有问题。

它规范地等价于

c3a9

那是 Utf-8 编码中的单个 Unicode 代码点。c3a9是带有锐音的拉丁文小写字母é E (U+00E9)。看起来您的数据库处理它没有问题,可能是因为它被数据库连接成功重新编码为Latin-1 / ISO-8859-1。

因此,我想到了两种处理数据的方法。它要么是数据重新编码的问题,要么是存储数据的问题。

只要您对组合的 unicode 代码点序列的分解感兴趣,您就应该采用Deceze 的回答中概述的规范化器。

您还可以允许将 UTF-8 存储到数据库中,这样您也应该没有问题。

此外,您可能无论如何都应该进行规范化,以便对数据库或程序中的数据进行排序和比较可以更好地工作。如您所见,二进制序列不同,这可能会导致在二进制级别上进行比较的所有内容出现问题。

当然,您可以节省一些流量 :)

于 2012-11-27T14:42:50.840 回答
0

有一个 tinymce 配置参数,可让您定义一个函数以在插入编辑器之前处理粘贴的内容:paste_preprocessing

使用该功能,您可以用所需的形式替换特殊字符

tinyMCE.init({
        ...
        paste_preprocess : function(pl, o) {
            // Content string containing the HTML from the clipboard
            o.content = o.content.replace(/\u2020/, 'x'); // example
        },
        paste_postprocess : function(pl, o) {
            ...
        },
        ...
});
于 2012-11-27T14:33:44.103 回答