Java 如何在忽略一个案例的情况下使用incombindingDiacriticalMarks
我正在为删除一个字符串的所有发音符号编写代码 例如:Java 如何在忽略一个案例的情况下使用incombindingDiacriticalMarks,java,regex,unicode,Java,Regex,Unicode,我正在为删除一个字符串的所有发音符号编写代码 例如: 我正在使用Unicode的属性来组合字符标记。但是我想忽略对ñ和ñ的替换 现在,我将在替换为之前保存这两个字符: s = s.replace('ñ', '\001'); s = s.replace('Ñ', '\002'); 可以在组合变音符号中使用,忽略ñ和的变音符号 这是我的代码: public static String stripAccents(String s) { /*Save ñ*/ s =
我正在使用Unicode的属性来组合字符标记。但是我想忽略对ñ
和ñ
的替换
现在,我将在替换为之前保存这两个字符:
s = s.replace('ñ', '\001');
s = s.replace('Ñ', '\002');
可以在组合变音符号中使用,忽略ñ和的变音符号
这是我的代码:
public static String stripAccents(String s)
{
/*Save ñ*/
s = s.replace('ñ', '\001');
s = s.replace('Ñ', '\002');
s = Normalizer.normalize(s, Normalizer.Form.NFD);
s = s.replaceAll("[\\p{InCombiningDiacriticalMarks}]", "");
/*Add ñ to s*/
s = s.replace('\001', 'ñ');
s = s.replace('\002', 'Ñ');
return s;
}
它工作正常,但我想知道是否可以优化此代码。这取决于您所说的“优化”是什么意思。从您编写的代码中减少代码行数是很困难的,但由于您要处理字符串六次,因此可以通过逐个字符只处理一次输入字符串来提高性能:
public class App {
// See SO answer https://stackoverflow.com/a/10831704/2985643 by virgo47
private static final String tab00c0
= "AAAAAAACEEEEIIII"
+ "DNOOOOO\u00d7\u00d8UUUUYI\u00df"
+ "aaaaaaaceeeeiiii"
+ "\u00f0nooooo\u00f7\u00f8uuuuy\u00fey"
+ "AaAaAaCcCcCcCcDd"
+ "DdEeEeEeEeEeGgGg"
+ "GgGgHhHhIiIiIiIi"
+ "IiJjJjKkkLlLlLlL"
+ "lLlNnNnNnnNnOoOo"
+ "OoOoRrRrRrSsSsSs"
+ "SsTtTtTtUuUuUuUu"
+ "UuUuWwYyYZzZzZzF";
public static void main(String[] args) {
var input = "AaBbCcáÁéÉíÍóÓúÚäÄëËïÏöÖüÜñÑçÇ";
var output = removeDiacritic(input);
System.out.println("input = " + input);
System.out.println("output = " + output);
}
public static String removeDiacritic(String input) {
var output = new StringBuilder(input.length());
for (var c : input.toCharArray()) {
if (isModifiable(c)) {
c = tab00c0.charAt(c - '\u00c0');
}
output.append(c);
}
return output.toString();
}
// Returns true if the supplied char is a candidate for diacritic removal.
static boolean isModifiable(char c) {
boolean modifiable;
if (c < '\u00c0' || c > '\u017f') {
modifiable = false;
} else {
modifiable = switch (c) {
case 'ñ', 'Ñ' ->
false;
default ->
true;
};
}
return modifiable;
}
}
输入字符串中没有变音符号的字符不会被修改。否则,除ñ
和ñ
的情况外,将删除变音符号(例如ch
至C
)
注:
- 代码根本不使用
规范化器
类或组合符号
。相反,它只处理输入字符串中的每个字符一次,如果合适,删除其重音。据我所知,去除变音符号的传统方法(如OP中所用)不支持选择性去除
- 该代码是基于,但增强,以支持选择性地删除口音。有关将重音字符映射到非重音字符的详细信息,请参见virgo47的答案
- 此解决方案仅适用于拉丁语-1/Latin-2,但可以进行增强以支持其他映射
- 您的解决方案非常简短且易于理解,但它感觉很脆弱,对于大量输入,我怀疑它比只处理每个字符一次的方法要慢得多
input = AaBbCcáÁéÉíÍóÓúÚäÄëËïÏöÖüÜñÑçÇ
output = AaBbCcaAeEiIoOuUaAeEiIoOuUñÑcC