【问题标题】:How to replace characters in a java String?如何替换java字符串中的字符?
【发布时间】:2010-04-16 14:37:44
【问题描述】:

我喜欢以一种有效的方式用相应的替换字符替换字符串的某一组字符。

例如:

String sourceCharacters = "šđćčŠĐĆČžŽ";
String targetCharacters = "sdccSDCCzZ";

String result = replaceChars("Gračišće", sourceCharacters , targetCharacters );

Assert.equals(result,"Gracisce") == true;

有没有比使用String类的replaceAll方法更有效的方法?

我的第一个想法是:

final String s = "Gračišće";
String sourceCharacters = "šđćčŠĐĆČžŽ";
String targetCharacters = "sdccSDCCzZ";

// preparation
final char[] sourceString = s.toCharArray();
final char result[] = new char[sourceString.length];
final char[] targetCharactersArray = targetCharacters.toCharArray();

// main work
for(int i=0,l=sourceString.length;i<l;++i)
{
  final int pos = sourceCharacters.indexOf(sourceString[i]);
  result[i] = pos!=-1 ? targetCharactersArray[pos] : sourceString[i];
}

// result
String resultString = new String(result);

有什么想法吗?

顺便说一句,UTF-8 字符造成了麻烦,使用 US_ASCII 可以正常工作。

【问题讨论】:

    标签: java string


    【解决方案1】:

    您可以使用java.text.Normalizer 和一个正则表达式来摆脱diacritics,其中存在的数量比您目前收集的要多得多。

    这是一个SSCCE,复制'n'粘贴'n'在Java 6上运行:

    package com.stackoverflow.q2653739;
    
    import java.text.Normalizer;
    import java.text.Normalizer.Form;
    
    public class Test {
    
        public static void main(String... args) {
            System.out.println(removeDiacriticalMarks("Gračišće"));
        }
    
        public static String removeDiacriticalMarks(String string) {
            return Normalizer.normalize(string, Form.NFD)
                .replaceAll("\\p{InCombiningDiacriticalMarks}+", "");
        }
    }
    

    这应该会产生

    恩典

    至少,它在 Eclipse 中将控制台字符编码设置为 UTF-8(Window > Preferences > General > Workspace > Text File Encoding)。确保在您的环境中也设置了相同的设置。

    作为替代方案,维护Map&lt;Character, Character&gt;

    Map<Character, Character> charReplacementMap = new HashMap<Character, Character>();
    charReplacementMap.put('š', 's');
    charReplacementMap.put('đ', 'd');
    // Put more here.
    
    String originalString = "Gračišće";
    StringBuilder builder = new StringBuilder();
    
    for (char currentChar : originalString.toCharArray()) {
        Character replacementChar = charReplacementMap.get(currentChar);
        builder.append(replacementChar != null ? replacementChar : currentChar);
    }
    
    String newString = builder.toString();
    

    【讨论】:

    • 通过这个解决方案我得到:GraA?iA¡Ae。顺便说一句,我不仅想替换变音符号,还想替换其他语言的其他一些字符。所以我真的很想知道一个适用于任意映射的解决方案。
    • 没错。问题是变音符号有时是组合的,有时不是,字符串逐字符替换会混淆,因为实际上有两个字符,而不是一个。
    • @Mr.闪亮新:是的,System.out.println("š".toCharArray().length);输出“2”
    • @Mr. Shiny 和@ManBurga:.replaceAll("\\p{InCombiningDiacriticalMarks}+", ""); 应该注意删除组合的变音符号。也许你删除了这条线?或者您正在运行一个古老的 Java 版本?上面的代码在这里工作了很多年,它适用于某些波兰字符的任意映射,例如带有连字符的 l,因为它不是变音符号。
    • @BalusC: 在 Vista 上使用 IntelliJ IDEA 的 java1.6,对不起,我无法让它工作。你能编辑你的帖子并添加导入吗?
    【解决方案2】:

    我会在一个简单的循环中使用replace 方法。

    String sourceCharacters = "šđćčŠĐĆČžŽ";
    String targetCharacters = "sdccSDCCzZ";
    
    String s = "Gračišće";
    for (int i=0 ; i<sourceCharacters.length() ; i++)
        s = s.replace(sourceCharacters.charAt[i], targetCharacters.charAt[i]);
    
    System.out.println(s);
    

    【讨论】:

    • 每次迭代都会创建一个新的字符串对象。 '就地'做会很好
    • 首先,每次迭代只在发生变化时生成一个新对象;如果要搜索的字符不存在,则返回原始对象。其次,使用StringBuilderStringBuffer 编写此代码更烦人,因为您必须自己完成所有工作;由于 Java 的内存管理无论如何都针对快速对象周转进行了调整,因此按照我展示的方式进行操作会更容易,而不是试图弄清楚如何提高效率。如果确实有必要(即,如果它是真正的瓶颈),您可以随时进行优化。
    • 是的,您的第一点是正确的。但我不同意你的第二个。您编写一次高效的代码,即使它很烦人,也可以重用它。无论如何,BalusC 解开了这个谜。
    猜你喜欢
    • 1970-01-01
    • 2015-12-23
    • 1970-01-01
    • 2013-07-09
    • 2010-11-17
    • 2021-01-27
    • 2012-06-27
    • 2023-02-23
    • 2015-05-01
    相关资源
    最近更新 更多