Tôi đã làm điều này gần đây trong 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;
}
Điều này sẽ làm như bạn đã chỉ định:
stripDiacritics("Björn") = Bjorn
nhưng nó sẽ không thành công trên ví dụ Białystok, vì ł
ký tự không có dấu.
Nếu bạn muốn có một chuỗi đơn giản hóa toàn diện, bạn sẽ cần một vòng làm sạch thứ hai, đối với một số ký tự đặc biệt hơn không phải là dấu phụ. Đây có phải là bản đồ, tôi đã bao gồm các ký tự đặc biệt phổ biến nhất xuất hiện trong tên khách hàng của chúng tôi. Nó không phải là một danh sách đầy đủ, nhưng nó sẽ cung cấp cho bạn ý tưởng về cách mở rộng nó. ImmutableMap chỉ là một lớp đơn giản từ bộ sưu tập google.
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()
.put(".", "")
.put("\"", "")
.put("'", "")
.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)
.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("\u0141", "l")
.put("\u0142", "l")
.put("ß", "ss")
.put("æ", "ae")
.put("ø", "o")
.put("©", "c")
.put("\u00D0", "d")
.put("\u00F0", "d")
.put("\u0110", "d")
.put("\u0111", "d")
.put("\u0189", "d")
.put("\u0256", "d")
.put("\u00DE", "th")
.put("\u00FE", "th")
.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) {
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();
}
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;
}
}