首页 > 解决方案 > 仅用双引号之外的字典替换字符

问题描述

我的代码:

String text="üçgen: \"üçgenin üç köşesi vardır\"";
//Translate: triangle: "a triangle has three corners"

String[] trChars = {"ç", "ğ", "ö", "ş", "ı", "ü", "Ç", "Ğ", "Ö", "Ş", "İ", "Ü"};
String[] enChars = {"c", "g", "o", "s", "i", "u", "C", "G", "O", "S", "I", "U"};
for (int i = 0; i < trChars.length; i++) {
    String regex = "(?<!\")"+ trChars[i] + "(?![\\w\\s]*[\"])";
    text = text.replaceAll(regex, enChars[i]);
}
System.out.println(text);

结果:

ucgen: "ücgenin uc kosesi vardır"

我想要的结果:

ucgen: "üçgenin üç köşesi vardır"

引号中的某些字符已更改,而有些则没有更改,而它们都应保持不变。

标签: javaregex

解决方案


您可以通过创建带有要搜索的键和要替换的值的单个字典来修复代码,并且仅在找到不在双引号内的匹配项时才替换匹配项:

String text="üçgen: \"üçgenin üç köşesi vardır\"";
//Translate: triangle: "a triangle has three corners"
 
String[] trChars = {"ç", "ğ", "ö", "ş", "ı", "ü", "Ç", "Ğ", "Ö", "Ş", "İ", "Ü"};
String[] enChars = {"c", "g", "o", "s", "i", "u", "C", "G", "O", "S", "I", "U"};
 
Map<String, String> dictionary = new HashMap<String, String>();
for (int i = 0; i < trChars.length; i++) {
    dictionary.put(trChars[i], enChars[i]);
}
 
StringBuffer result = new StringBuffer();
Matcher m = Pattern.compile("\"[^\"]*\"|([" + String.join("", trChars) + "])").matcher(text);
while (m.find()) {
    if (m.group(1) != null) {
        m.appendReplacement(result, dictionary.get(m.group(1)));
    } else {
        m.appendReplacement(result, m.group());
    }
}
m.appendTail(result);
System.out.println(result.toString());
// => ucgen: "üçgenin üç köşesi vardır"

在线查看Java 代码

正则表达式看起来像 "[^"]*"|([çğöşıüÇĞÖŞİÜ]),一旦找到匹配并且第 1 组不为空,dictionary.get(m.group(1))将获取找到的土耳其字母的相应 ASCII 值。否则,双引号之间的字符串将按原样返回。


推荐阅读