我正在将表格转换为人类可读的形式,并且我需要“以独特的方式”处理零长度 Unicode 字符的内容。
识别它们的唯一方法似乎是(即使有 Perl 的扩展!)列出所有“妨碍”的可能性(我在表格中发现的是 CGJ、ZW [非]连接器和 r2l/l2r 标记)。我尝试使用 Perl 的 `\p{XPosixPrint},但失败了:
perl -we "print(qq(\n)), print, print qq(\t), (chr hex) =~ /\p{XPosixPrint}/ for @ARGV" 034f 200c 200d 200e 200f
034f 1
200c 1
200d 1
200e 1
200f 1
我错过了什么吗:是否有一个
\p{…}
(的组合)可以匹配零宽度Unicode字符(并且仅匹配它们)?
不,Unicode 标准中没有专门用于此目的的字符属性,但您所追求的一个很好的近似可能是
Default_Ignorable_Code_Point
,如 DerivedCoreProperties.txt 数据文件中所定义。该属性集包括:
零宽度并不是 Unicode 标准中定义的概念,因此您可能仍需要根据您的具体需求对字符集进行一些调整。例如,“行间注释”格式控件 (U+FFF9..U+FFFB) 被故意排除在
Default_Ignorable_Code_Point
属性之外,尽管它非常符合零宽度字符的标准。
Default_Ignorable_Code_Point
的目的是标记字符,如果不支持,则在渲染文本时应完全丢弃这些字符,而不是像大多数其他字符那样用占位符字形(例如框或问号)替换人物。当然,这包括许多本来就不可见的角色。但是,其中一些不可见字符对于解析它们出现的文本结构非常重要。如果它们没有得到适当的支持,那么实际上最好的做法是用可见的占位符来表示它们,以便读者至少知道某些东西他们最后出了问题。这就是为什么像前面提到的行间注释控件这样的字符显然不能默认忽略。由于同样的原因,C0 和 C1 控件(
gc=Cc
,即 U+0000..U+001F 和 U+007F..U+009F)不可默认忽略。还有其他无法轻易解决的边缘情况。例如,U+1D159 MUSICAL SYMBOL NULL NOTHEAD 是否不可见且为零宽度完全取决于当前用于显示它的字体的随意性。在许多书写系统中还存在所谓的“隐形堆叠器”(
Indic_Syllabic_Category=Invisible_Stacker
),它们是零宽度组合标记,可以修改相邻字符的外观,而本身不可见除了当它们被用于无效或无效时。不完整的序列,在这种情况下,它们可能会或可能不会显示,具体取决于字体和文本渲染器。这些字符都不是默认可忽略的。 如果您的目标是根据您的个人标准捕获 100% 的“妨碍”字符,您将必须保留一个自定义字符列表,并准备好在每个新的 Unicode 版本中更新它。如果 99% 足够好,我建议简单地依赖
Default_Ignorable_Code_Point
属性以及一些硬编码的附加内容,例如行间注释以及 C0 和 C1 集。这里讨论的大多数字符都非常晦涩难懂,不太可能出现在正常的文本数据中。