Java从Unicode字符中删除变音符(criticalñṅņṋṉɳȵȵ)

我正在寻找一种算法,该算法可以在带有变音符号的字符(tilde,circumflex,caret,umlaut,caron)与其“简单”字符之间进行映射。

例如:

ń  ǹ  ň  ñ  ṅ  ņ  ṇ  ṋ  ṉ  ̈  ɲ  ƞ ᶇ ɳ ȵ  --> n

á --> a

ä --> a

ấ --> a

ṏ --> o

等等。

  1. 我想用Java做到这一点,尽管我怀疑它应该是Unicode-y,并且应该可以轻松地以任何语言进行操作。

  2. 目的:允许轻松搜索带有变音标记的单词。例如,如果我有一个网球运动员数据库,并且输入了Björn_Borg,我还将保留Bjorn_Borg,以便在有人进入Bjorn而不是Björn的情况下可以找到它。

回答:

我最近在Java中完成了此操作:

public static final Pattern DIACRITICS_AND_FRIENDS

= Pattern.compile("[\\p{InCombiningDiacriticalMarks}\\p{IsLm}\\p{IsSk}]+");

private static String stripDiacritics(String str) {

str = Normalizer.normalize(str, Normalizer.Form.NFD);

str = DIACRITICS_AND_FRIENDS.matcher(str).replaceAll("");

return str;

}

这将按照你指定的方式进行:

stripDiacritics("Björn")  = Bjorn

但由于诸如Białystok之类的ł人物不讲字,因此它将失败。

如果要使用功能强大的字符串简化程序,则需要进行第二轮清理,以获取一些不是变音符号的特殊字符。是这张地图,我包括了出现在我们客户名称中的最常见的特殊字符。它不是一个完整的列表,但是会为你提供扩展方法的想法。immutableMap只是google-collections中的一个简单类。

public class StringSimplifier {

public static final char DEFAULT_REPLACE_CHAR = '-';

public static final String DEFAULT_REPLACE = String.valueOf(DEFAULT_REPLACE_CHAR);

private static final ImmutableMap<String, String> NONDIACRITICS = ImmutableMap.<String, String>builder()

//Remove crap strings with no sematics

.put(".", "")

.put("\"", "")

.put("'", "")

//Keep relevant characters as seperation

.put(" ", DEFAULT_REPLACE)

.put("]", DEFAULT_REPLACE)

.put("[", DEFAULT_REPLACE)

.put(")", DEFAULT_REPLACE)

.put("(", DEFAULT_REPLACE)

.put("=", DEFAULT_REPLACE)

.put("!", DEFAULT_REPLACE)

.put("/", DEFAULT_REPLACE)

.put("\\", DEFAULT_REPLACE)

.put("&", DEFAULT_REPLACE)

.put(",", DEFAULT_REPLACE)

.put("?", DEFAULT_REPLACE)

.put("°", DEFAULT_REPLACE) //Remove ?? is diacritic?

.put("|", DEFAULT_REPLACE)

.put("<", DEFAULT_REPLACE)

.put(">", DEFAULT_REPLACE)

.put(";", DEFAULT_REPLACE)

.put(":", DEFAULT_REPLACE)

.put("_", DEFAULT_REPLACE)

.put("#", DEFAULT_REPLACE)

.put("~", DEFAULT_REPLACE)

.put("+", DEFAULT_REPLACE)

.put("*", DEFAULT_REPLACE)

//Replace non-diacritics as their equivalent characters

.put("\u0141", "l") // BiaLystock

.put("\u0142", "l") // Bialystock

.put("ß", "ss")

.put("æ", "ae")

.put("ø", "o")

.put("©", "c")

.put("\u00D0", "d") // All Ð ð from http://de.wikipedia.org/wiki/%C3%90

.put("\u00F0", "d")

.put("\u0110", "d")

.put("\u0111", "d")

.put("\u0189", "d")

.put("\u0256", "d")

.put("\u00DE", "th") // thorn Þ

.put("\u00FE", "th") // thorn þ

.build();

public static String simplifiedString(String orig) {

String str = orig;

if (str == null) {

return null;

}

str = stripDiacritics(str);

str = stripNonDiacritics(str);

if (str.length() == 0) {

// Ugly special case to work around non-existing empty strings

// in Oracle. Store original crapstring as simplified.

// It would return an empty string if Oracle could store it.

return orig;

}

return str.toLowerCase();

}

private static String stripNonDiacritics(String orig) {

StringBuffer ret = new StringBuffer();

String lastchar = null;

for (int i = 0; i < orig.length(); i++) {

String source = orig.substring(i, i + 1);

String replace = NONDIACRITICS.get(source);

String toReplace = replace == null ? String.valueOf(source) : replace;

if (DEFAULT_REPLACE.equals(lastchar) && DEFAULT_REPLACE.equals(toReplace)) {

toReplace = "";

} else {

lastchar = toReplace;

}

ret.append(toReplace);

}

if (ret.length() > 0 && DEFAULT_REPLACE_CHAR == ret.charAt(ret.length() - 1)) {

ret.deleteCharAt(ret.length() - 1);

}

return ret.toString();

}

/*

Special regular expression character ranges relevant for simplification -> see http://docstore.mik.ua/orelly/perl/prog3/ch05_04.htm

InCombiningDiacriticalMarks: special marks that are part of "normal" ä, ö, î etc..

IsSk: Symbol, Modifier see http://www.fileformat.info/info/unicode/category/Sk/list.htm

IsLm: Letter, Modifier see http://www.fileformat.info/info/unicode/category/Lm/list.htm

*/

public static final Pattern DIACRITICS_AND_FRIENDS

= Pattern.compile("[\\p{InCombiningDiacriticalMarks}\\p{IsLm}\\p{IsSk}]+");

private static String stripDiacritics(String str) {

str = Normalizer.normalize(str, Normalizer.Form.NFD);

str = DIACRITICS_AND_FRIENDS.matcher(str).replaceAll("");

return str;

}

}

以上是 Java从Unicode字符中删除变音符(criticalñṅņṋṉɳȵȵ) 的全部内容, 来源链接: utcz.com/qa/399937.html

回到顶部