我正在尝试将西里尔字母变成拉丁语,这样我就可以将它们放在网址中。我使用 icu4j 音译器,但它仍然给出这样奇怪的字符:Vilʹândimaa。它应该更像viljandimaa。当我复制该网址时,这些字母会变成 %.. 一些无用的东西。
有人知道如何使用 icu4j 将西里尔字母转换为 a-z 吗?
更新
已经无法回答自己,但发现这个问题非常有帮助:Converting Symbols, Accent Letters to English Alphabet
修改您的标识符以执行您想要的操作。您可以使用带有
Remove
转换的正则表达式去除不需要的字符。
例如,考虑字符串 "'Eé математика":
"'E\u00E9 \u043c\u0430\u0442\u0435\u043c\u0430\u0442\u0438\u043a\u0430"
标识符
"Any-Latin; NFD; [^\\p{Alnum}] Remove"
将音译为拉丁语(可能仍包含重音符号),将重音字符分解为字母和变音符号,并删除任何非字母数字的内容。结果字符串是“Eematematika”。
您可以在 ICU 网站上的General Transforms下阅读有关标识符的更多信息。
示例:
//import com.ibm.icu.text.Transliterator;
String greek
= "'E\u00E9 \u043c\u0430\u0442\u0435\u043c\u0430\u0442\u0438\u043a\u0430";
String id = "Any-Latin; NFD; [^\\p{Alnum}] Remove";
String latin = Transliterator.getInstance(id)
.transform(greek);
System.out.println(latin);
根据 ICU4J 49.1 进行测试。
看看: https://ru.stackoverflow.com/questions/633355/Показать-правильный-пример-транслитерации-на-java
添加依赖性:
<dependency>
<groupId>com.ibm.icu</groupId>
<artifactId>icu4j</artifactId>
<version>63.1</version>
</dependency>
并音译:
var CYRILLIC_TO_LATIN = "Latin-Russian/BGN"
// var CYRILLIC_TO_LATIN = "Russian-Latin/BGN"
Transliterator toLatinTrans = Transliterator.getInstance(CYRILLIC_TO_LATIN);
String result = toLatinTrans.transliterate(st);
System.out.println(result);
System.out.println(TransliterationUtil.transliterate("Съешь этих мягких французских булок"));
标准输出:
Sesh etih mjagkih frantsuzskih bulok
public class TransliterationUtil {
private TransliterationUtil() {
}
private static final Map<Character, String> cyrToLatMap;
static {
cyrToLatMap = new HashMap<>();
cyrToLatMap.put(' ', " ");
cyrToLatMap.put('а', "a");
cyrToLatMap.put('б', "b");
cyrToLatMap.put('в', "v");
cyrToLatMap.put('г', "g");
cyrToLatMap.put('д', "d");
cyrToLatMap.put('е', "e");
cyrToLatMap.put('ё', "e");
cyrToLatMap.put('ж', "zh");
cyrToLatMap.put('з', "z");
cyrToLatMap.put('и', "i");
cyrToLatMap.put('й', "y");
cyrToLatMap.put('к', "k");
cyrToLatMap.put('л', "l");
cyrToLatMap.put('м', "m");
cyrToLatMap.put('н', "n");
cyrToLatMap.put('о', "o");
cyrToLatMap.put('п', "p");
cyrToLatMap.put('р', "r");
cyrToLatMap.put('с', "s");
cyrToLatMap.put('т', "t");
cyrToLatMap.put('у', "u");
cyrToLatMap.put('ф', "f");
cyrToLatMap.put('х', "h");
cyrToLatMap.put('ц', "ts");
cyrToLatMap.put('ч', "ch");
cyrToLatMap.put('ш', "sh");
cyrToLatMap.put('щ', "sch");
cyrToLatMap.put('ъ', "");
cyrToLatMap.put('ы', "i");
cyrToLatMap.put('ь', "");
cyrToLatMap.put('э', "e");
cyrToLatMap.put('ю', "ju");
cyrToLatMap.put('я', "ja");
cyrToLatMap.put('А', "A");
cyrToLatMap.put('Б', "B");
cyrToLatMap.put('В', "V");
cyrToLatMap.put('Г', "G");
cyrToLatMap.put('Д', "D");
cyrToLatMap.put('Е', "E");
cyrToLatMap.put('Ё', "E");
cyrToLatMap.put('Ж', "Zh");
cyrToLatMap.put('З', "Z");
cyrToLatMap.put('И', "I");
cyrToLatMap.put('Й', "Y");
cyrToLatMap.put('К', "K");
cyrToLatMap.put('Л', "L");
cyrToLatMap.put('М', "M");
cyrToLatMap.put('Н', "N");
cyrToLatMap.put('О', "O");
cyrToLatMap.put('П', "P");
cyrToLatMap.put('Р', "R");
cyrToLatMap.put('С', "S");
cyrToLatMap.put('Т', "T");
cyrToLatMap.put('У', "U");
cyrToLatMap.put('Ф', "F");
cyrToLatMap.put('Х', "H");
cyrToLatMap.put('Ц', "Ts");
cyrToLatMap.put('Ч', "Ch");
cyrToLatMap.put('Ш', "Sh");
cyrToLatMap.put('Щ', "Sch");
cyrToLatMap.put('Ъ', "");
cyrToLatMap.put('Ы', "I");
cyrToLatMap.put('Ь', "");
cyrToLatMap.put('Э', "E");
cyrToLatMap.put('Ю', "Ju");
cyrToLatMap.put('Я', "Ja");
}
public static String transliterate(String message){
StringBuilder builder = new StringBuilder();
for (var ch : message.toCharArray()) {
builder.append(cyrToLatMap.getOrDefault(ch,"?"));
}
return builder.toString();
}
}
不知道 icu4j,但是 在 Unicode 表中西里尔字母只占很小的范围。我不会依赖工作不明确的第三方库,而是为每个西里尔字母定义一个音译序列并自己进行翻译。
附注“viljandimaa”这个词来自什么语言?对我来说听起来不像西里尔语...