java - ICU 音译片假名过滤器不适用于半角片假名浊音标记

标签 java unicode icu

我正在尝试使用 ICU Transliterator 对某些文本进行非常具体的转换,如 here 中所述。 .

我的文本包含半角片假名字符和常规拉丁字符。我想将半角片假名转换为全角片假名,同时保持非片假名字符不变。

我想简单地将标准“半角-全角”ICU 转换与仅选择片假名的过滤器一起应用,但这不起作用 - 片假名过滤器不适用于 Halfwidth Katakana Voiced Sound Mark ,这让我很惊讶。我试图弄清楚这是有意为之还是一个错误。

请参阅下面的代码以获取示例。我尝试过:

  1. 没有过滤器的半角-全角 - 影响太大
  2. 带有片假名过滤器的半角-全角 - 不影响 U+ff9e - 这是一个错误吗?
  3. 带有负拉丁语过滤器的半角-全角 - 空格仍然受影响。
  4. 带有复合负滤镜的半角-全角 - 太脆弱了。

有什么想法吗? 有什么地方可以检查 ICU [:Katakana:] 过滤器中实际包含哪些字符?

void transliterateWithRules(String original, String rules) {
    Transliterator transliterator = Transliterator.createFromRules("mytest", rules, Transliterator.FORWARD);
    String result = transliterator.transliterate(original);
    System.out.println(String.format("Transliteration result: \"%s\", codepoints: %s", result, toCodepoints(result)));
}

void test() {
    String input = "ギ a"; // Unicode Codepoints: \uff77 \uff9e \u20 \u61

    transliterateWithRules(input, ":: Halfwidth-Fullwidth;");
    // Result:
    // "ギ a", codepoints: \u30ae \u3000 \uff41
    // This makes everything fullwidth, including the space and the latin 'a'

    transliterateWithRules(input, "::  [:Katakana:]; :: Halfwidth-Fullwidth;");
    // Result:
    // "ギ a", codepoints: \u30ad \uff9e \u20 \u61
    // This makes the Katakana KI fullwidth, and skips the space and 'a' as intended, but it also
    // skips the Halfwidth Katakana Voiced Sound Mark (U+FF9E), which I expected to be converted.

    transliterateWithRules(input, ":: [:^Latin:] Halfwidth-Fullwidth;");
    // Result:
    // "ギ a", codepoints: \u30ae \u3000 \u61
    // Skips the latin 'a' as intended, but makes the space Fullwidth, which I don't want

    transliterateWithRules(input, ":: [[:^Latin:]&[^\\ ]]; :: Halfwidth-Fullwidth;");
    // Result:
    // "ギ a", codepoints: \u30ae \u20 \u61
    // Exactly what I want, for this example - but relying on a list of exclusions is fragile, since I am only
    // excluding what I currently know about.
}

最佳答案

您可以看到 [:Katakana:] 集中的字符列表 here ,其中既不包含 U+FF9E 也不包含 U+FF9F

这是因为 [:Katakana:] 相当于 [:Script=Katakana:],它测试 "Script" property一个角色的。 U+FF9EU+FF9F 都被标记为在平假名片假名文本中使用,因此它们的脚本属性是“通用”(而不是而不是像 这样的东西,它完全是“片假名”)。有一个包含两个脚本的“脚本扩展”属性,但 [:Katakana:] 不会检查此属性。

您可以手动将它们添加到集合中 ([[:Katakana:]\uFF9E\uFF9F]),或者创建一个包含脚本扩展的集合:

[\p{sc=Katakana}\p{scx=Katakana}]

(请注意,这还包含一些其他共享字符。)

关于java - ICU 音译片假名过滤器不适用于半角片假名浊音标记,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32524917/

相关文章:

Java JSSE SSLEngine 无法恢复 SSL session

java - 通过将运行时参数传递给 java Reflect 方法进行单元测试

css - 如何修复 Windows 上异常字符的等宽间距?

unicode - 按特定字形划分字体子集

c++ - 构建库时未定义对 `utf8_nextCharSafeBody_48' icu4c 的引用

java - 如何迭代结果集并向对象添加值?

java - Json to Java POJO with Jackson API Hangouts

perl - Pango:在梵文字符串中查找位置

c++ - 使用 icu 库将 UTF-8 转换为 UCS-2

c# - C#'s StringInfo and TextElementEnumerator can' t 正确识别字素