java取代德语变音符号

时间:2015-09-21 13:16:17

标签: java

我有以下问题。我试图在java中替换像äöü这样的德语变音符号。但它根本行不通。这是我的代码:

private static String[][] UMLAUT_REPLACEMENTS = { { "Ä", "Ae" }, { "Ü", "Ue" }, { "Ö", "Oe" }, { "ä", "ae" }, { "ü", "ue" }, { "ö", "oe" }, { "ß", "ss" } };
public static String replaceUmlaute(String orig) {
    String result = orig;

    for (int i = 0; i < UMLAUT_REPLACEMENTS.length; i++) {
        result = result.replaceAll(UMLAUT_REPLACEMENTS[i][0], UMLAUT_REPLACEMENTS[i][1]);
    }

    return result;
}

ä仍为ä,依此类推。我不知道这个问题是否与编码有关,但String包含我试图替换的确切字符。

提前谢谢

9 个答案:

答案 0 :(得分:15)

首先,Unicode中存在一个小问题:

  • ä可能是一个代码点SMALL_LETTER_A_WITH_UMLAUT或 两个代码点:SMALL_LETTER_A后跟COMBINING_DIACRITICAL_MARK_UMLAUT。

为此,可以规范化 Unicode文本。

s = Normalizer.normalize(s, Normalizer.Form.NFKC);

C表示撰写,并会产生紧凑版本。

第二个更棘手的问题是,编辑器中java源代码的编码必须与javac -encoding ...编译器的编码相同。

您可以使用(测试方式)u-escaping:

来测试编码是否正确
"\u00E4" // instead of ä

我的猜测是,这可能是问题所在。国际规范似乎已经成为使用UTF-8进行Java源代码和编译。

此外,您可以使用

    result = result.replace(UMLAUT_REPLACEMENTS[i][0], UMLAUT_REPLACEMENTS[i][1]);

没有正则表达式替换,速度更快。

答案 1 :(得分:7)

您的代码看起来很好,replaceAll()应该按预期工作。

尝试此操作,如果您还想保留大小写(例如ÜBUNG将成为UEBUNG,而不是UeBUNG):

private static String replaceUmlaut(String input) {

     //replace all lower Umlauts
     String output = input.replace("ü", "ue")
                          .replace("ö", "oe")
                          .replace("ä", "ae")
                          .replace("ß", "ss");

     //first replace all capital umlaute in a non-capitalized context (e.g. Übung)
     output = output.replace("Ü(?=[a-zäöüß ])", "Ue")
                    .replace("Ö(?=[a-zäöüß ])", "Oe")
                    .replace("Ä(?=[a-zäöüß ])", "Ae");

     //now replace all the other capital umlaute
     output = output.replace("Ü", "UE")
                    .replace("Ö", "OE")
                    .replace("Ä", "AE");

     return output;
 }

Source

答案 2 :(得分:6)

这最终对我有用:

private static String[][] UMLAUT_REPLACEMENTS = { { new String("Ä"), "Ae" }, { new String("Ü"), "Ue" }, { new String("Ö"), "Oe" }, { new String("ä"), "ae" }, { new String("ü"), "ue" }, { new String("ö"), "oe" }, { new String("ß"), "ss" } };
public static String replaceUmlaute(String orig) {
    String result = orig;

    for (int i = 0; i < UMLAUT_REPLACEMENTS.length; i++) {
        result = result.replace(UMLAUT_REPLACEMENTS[i][0], UMLAUT_REPLACEMENTS[i][1]);
    }

    return result;
}

感谢您的所有答案和帮助。它最终是nafas(带有新String)和Joop Eggen(正确的replace-Statement)的混合体。 你得到了我的upvote非常感谢!

答案 3 :(得分:2)

编码编码编码....

不同的输入源可能会导致String编码的复杂化。例如,一个可能有UTF-8个编码,而另一个可能是ISO

有人建议代码适合他们,因此,最有可能的是你的字符串在处理时有不同的编码。 (不同的编码会产生不同的字节数组,因此无法替换...)

从根本上解决您的问题,您必须确保每个源使用完全相同的编码。

尝试此练习,希望能帮助您解决问题:

1 - 试试这个:

System.out.println(Arrays.asList("Ä".getBytes());  //1 and 2 should have same results
System.out.println(Arrays.asList(new String("Ä","UTF-8").getBytes()); //1 and 2 should have same results
System.out.println(Arrays.asList(new String("Ä","UTF-32").getBytes()); //should have a different results from one and two
System.out.println(Arrays.asList(orig.getBytes()); //look for representation and search for pattenr of numbers (this bit is the hard bit I guess).
System.out.println(Arrays.asList(new String(orig,"UTF-32").getBytes()); //look for representation and search for pattenr of numbers (this bit is the hard bit I guess).

下一步是查看orgi字符串是如何形成的。例如,如果您是从网络收到的,请确保您的POST和GET方法正在使用您的首选编码

编辑1:

试试这个:

{ { new String("Ä".getBytes(),"UTF-8"), "Ae" }, ... };

如果这个没有工作,试试这个:

    byte[] bytes = {-61,-124}; //byte representation of Ä in utf-8
    String Ae = new String(bytes,"UTF-8");
    { { Ae, "Ae" }, ... }; //and do for the rest

答案 4 :(得分:1)

我只是试图运行它并且运行正常。

如果您不使用正则表达式,那么我使用string.replace而不是string.replaceAll,因为它比后者略快一些。它们之间的区别主要在于replaceAll可以处理正则表达式。

编辑:注意到评论中的人在我面前说了同样的内容,所以如果您已经阅读过,那么您几乎可以忽略我所说的内容,因为该代码中的其他地方存在问题,因为该代码段的工作方式如下所示预期

答案 5 :(得分:1)

我尝试时工作正常,所以它必须是编码问题。

检查您的系统编码。您可能希望将-encoding UTF-8添加到javac编译器命令行。

      -encoding encoding
         Set the source file encoding name, such as EUC-JP and UTF-8. If -encoding is not specified, the platform default converter is used.

答案 6 :(得分:0)

我不得不修改user1438038的答案:

private static String replaceUmlaute(String output) {
    String newString = output.replace("\u00fc", "ue")
            .replace("\u00f6", "oe")
            .replace("\u00e4", "ae")
            .replace("\u00df", "ss")
            .replaceAll("\u00dc(?=[a-z\u00e4\u00f6\u00fc\u00df ])", "Ue")
            .replaceAll("\u00d6(?=[a-z\u00e4\u00f6\u00fc\u00df ])", "Oe")
            .replaceAll("\u00c4(?=[a-z\u00e4\u00f6\u00fc\u00df ])", "Ae")
            .replace("\u00dc", "UE")
            .replace("\u00d6", "OE")
            .replace("\u00c4", "AE");
    return newString;
}

这应该适用于任何目标平台(我在Windows上的tomcat上遇到问题)。

答案 7 :(得分:0)

如果您在项目中使用Apache Commons或Commons3,那么使用类似这样的类将是最有效的

public class UmlautCleaner {

    private static final String[] UMLAUTE = new String[] {"Ä", "Ö", "Ü", "ä", "ö", "ü", "ß"};
    private static final String[] UMLAUTE_REPLACEMENT = new String[] {"AE", "OE", "UE", "ae", "oe", "ue", "ss"};

    private UmlautCleaner() {
    }

    public static String cleanSonderzeichen(final String s) {
        return StringUtils.stripAccents(StringUtils.replaceEach(s, UMLAUTE, UMLAUTE_REPLACEMENT));
    }
}

答案 8 :(得分:0)

一个简短的解决方案是使用音译:

Transliterator transliterator = Transliterator.getInstance("de-ASCII");
String umlautReplaced = transliterator.transliterate(text);