2015-09-21 159 views
8

我有以下问题。我试图用java代替德语变音符号,如ä,ö,ü in 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; 
} 

ä仍然是一个ä等。我不知道这个问题是否与编码有关,但字符串包含我试图替换的确切字符。

预先感谢您

+2

我刚刚测试过,并且按预期工作,问题必须出现在别处。 – Tunaki

+1

按预期工作。你应该考虑使用'String#replace'而不是'String#replaceAll',因为你正在处理文字而不是正则表达式。 – Mena

+0

你可能想检查你的方法输入。你如何输入该方法的数据?硬编码?通过CLI? – Jan

回答

4

这终于为我工作:

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(正确的替换声明)的混合体。 你有我的upvote非常感谢!

5

您的代码看起来不错,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

+1

不错,智能处理Ue/UE。 ('o_str ...'然而痒)。您可能想要使用替换i.o.全部替换。 –

+0

@JoopEggen:纳入你的建议,谢谢。 – user1438038

+1

这对我不起作用。使用这种方法后,我的字符串根本没有改变。 ä依然存在。 – user2841991

1

我只是试图运行它,它运行良好。

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

编辑:刚才注意到人们在评论中有这样的说法,所以如果你已经阅读了这些,你几乎可以忽略我所说的,正如所述的问题存在于代码中的其他地方,因为该片段按预期工作。

11

首先出现的是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转义:

"\u00E4" // instead of ä 

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

此外,您可以使用

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

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

+0

谢谢你的回答。我的编码似乎是正确的。如果我正在写“String test =”\ u00E4“;”我调试它的字符串包含字符“ä”。但是规范化陈述是什么呢?我在替换字符之前使用了它,但到目前为止它没有改变任何东西。 – user2841991

+1

在这种情况下,使用NKC/NFKC,它将用单个字符''替代任何双字符版本的'ä'(普通拉丁字母加零宽度变音符号)。视觉表示不应该不同,但字符串有不同的长度。 NKD/NFKD(分解)可用于基本信件的国际订购,在'c ...'之后放置'ĉ...'而不考虑区域设置。 –

+0

我不明白。我想要另一种方式。我想用ae代替ä。为什么视觉表示没有不同?这正是我需要改变的,代表性。 – user2841991

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. 
2

ENCODING编码方式进行编码....

输入的不同的源可以导致在字符串编码并发症。例如一个人可能有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 
+0

前两行对我来说没有相同的结果。 – user2841991

+0

@ user2841991然后检查编辑队友,它很可能会解决您的问题 – nafas

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的问题)。