Unicode 日文延长的声音标记被排除在假名脚本之外?

Unicode Japanese prolonged sound mark excluded from Kana script?

我正在尝试通过删除特殊字符来清理字符串以生成 slug。也就是说,我想保留 CJK 字符,否则这些语言将一无所有。

所以我有一个正则表达式,它应该通过列出脚本来保留 CJK 字符:

"[^-_.\w-\p{script=Han}\p{script=Hira}\p{script=Kana}\p{script=Hang}]"

问题是,片假名长音标记“ー”似乎被排除了。

http://www.unicodemap.org/details/0x30FC/index.html

这是显示问题的代码:

https://github.com/erwan/unicode-java-issue/blob/master/src/main/java/com/example/Hello.java

我列出的脚本里没有吗?

编辑:好的,如果您愿意,可以在此处编码,但它所提供的信息并不比正则表达式本身多得多。它非常有用,所以人们可以尝试一下。

package com.example;

class Hello {
    public static void main(String[] args) {
        String input = "%;アレルギー[]abcd";
        String output= input.replaceAll("[^-_.\w-\p{script=Han}\p{script=Hira}\p{script=Kana}\p{script=Hang}]", "");
        System.out.println(output);
    }
}

为了避免匹配那个字符,你应该把它添加到取反的class。

"[^-_ー.\w-\p{script=Han}\p{script=Hira}\p{script=Kana}\p{script=Hang}]"

不,事实上,它不在列出的脚本中。 Unicode Standard 将此字符放在 Common 脚本中。

应该区分 Unicode 中的 "script" 和 "block"。该字符属于片假名 ,还有其他一些不是字母的字符,例如 "Katakana iteration mark" (\u30fd)。但不属于片假名文字。只有实际音节属于片假名脚本。

您可以做的一件事是将 script 指示替换为 block for Katakana:

output = input.replaceAll("[^-_.\w-\p{script=Han}\p{script=Hira}\p{block=Katakana}\p{script=Hang}]", "");

这种情况下的输出将包括延长的声音标记。

或者你可以这样做:

Matcher m = Pattern.compile("[^-_.\w]",Pattern.UNICODE_CHARACTER_CLASS).matcher(input);
output = m.replaceAll("");

此模式将匹配所有语言的所有单词字符,包括但不限于日语。

对于输入字符串 "%;アレルギー[]{}=abceⸯd漢字ру́сский",这将产生

アレルギーabceⸯd漢字ру́сский

而我的第一个建议,带有块的那个,输出将是:

アレルギーabced漢字

因此,如果您只想限制为日语(和韩语),我的第一个建议可能更适合您,而如果您想要所有国际单词字符,第二个会更好。