【问题标题】:Strange umlaut encoding on file system文件系统上奇怪的变音符号编码
【发布时间】:2015-10-25 11:50:50
【问题描述】:

有时我会遇到文件名中的元音变音字符编码奇怪(错误?)的文件。也许编码来自Mac系统,但我不确定。我使用 Windows。

例如: Volkszählung 而不是 Volkszählung(尝试在第一个 ä 后使用 Backspace)。

使用 notepad++ 将其粘贴到 ANSI 编码文件中时,它会插入 Volksza¨hlung

我有两个问题:
a) 那是从哪里来的?它是哪种编码?
b) 在 PHP 中使用 glob() 在使用通配符 * 时不会列出这些文件。如何在 PHP 中检测到它们?

【问题讨论】:

  • 这就是Unicode预组合字符和组合字符之间的区别。如果 Notepad++ 将这两个部分视为单独的字符,那么它的 Unicode 支持肯定很差。
  • 您的问题似乎是您使用的操作系统正在创建名称不符合正确 Unicode 规范化规则的文件。不知道如何处理。
  • @Andrea,这不是真正的根本问题;即使这个特定的字符串使用了预先组合的字符,应用程序也可能遇到其他无法规范化的字符串,因为不存在预先组合的字符。它需要能够处理组合字符。
  • @Wyzard 我知道,但我提到的问题是他们的文件系统显然混合了各种表示

标签: php encoding diacritics


【解决方案1】:

那是combining character:具体来说,U+0308 结合 DIARESIS。组合字符可以让您在 any 字符上放置诸如变音符号之类的东西,而不仅仅是带有内置变音符号的特定“预组合”字符,例如带有分音符号的 U+00E4 拉丁小写字母 A。虽然在这种情况下使用组合字符不是必要(因为存在合适的预组合字符),但也没有错误

(请注意,这根本不是“编码”:在 Unicode 的上下文中,编码是一种将 Unicode codepoint 数字转换为字节序列以便它们可以存储在文件中的方法。UTF-8和 UTF-16 是编码。但是组合字符是 Unicode 代码点,就像普通字符一样;它们不是由编码过程产生的。)

如果您使用的是 Unicode 文本,您应该使用 PHP 的 mbstring 函数。内置字符串函数不支持 Unicode,并且仅将字符串视为字节序列而不是字符序列。不过,我不确定 mbstring 如何处理组合字符;据我所知,文档根本没有提到它们。

您还应该查看grapheme functions,它专门用于处理组合字符。 “字素单元”是由基本字符代码点加上其后的任何组合字符产生的单个视觉字符。

最后,PCRE regex functions 支持 \X escape sequence 匹配整个字素簇而不是单个代码点。

【讨论】:

  • 感谢您的解释!但我仍然无法访问文件名中包含组合字符的文件。 scandir() 列出文件,但 file_exists() 否认它们的存在。但是,这适用于像 U+00E4 这样的“真实”变音符号(即我使用正确的编码)。如上所述,glob() 甚至没有列出这些文件。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-31
  • 1970-01-01
  • 2014-04-19
  • 2014-03-20
  • 2015-04-20
相关资源
最近更新 更多