使用StringBuilder替换所有出现的String?

时间:2010-08-12 22:55:25

标签: java

我是否遗漏了某些内容,或者StringBuilder是否缺少与普通String类相同的“将所有出现的字符串A替换为字符串B”的函数? StringBuilder替换功能并不完全相同。有没有办法更有效地使用普通的String类生成多个字符串?

13 个答案:

答案 0 :(得分:70)

好吧,你可以写一个循环:

public static void replaceAll(StringBuilder builder, String from, String to)
{
    int index = builder.indexOf(from);
    while (index != -1)
    {
        builder.replace(index, index + from.length(), to);
        index += to.length(); // Move to the end of the replacement
        index = builder.indexOf(from, index);
    }
}

请注意,在某些情况下,使用lastIndexOf可能会更快,从后面开始工作。我怀疑如果你用一个短字符串替换长字符串就是这种情况 - 所以当你开始时,任何替换都要少复制。无论如何,这应该给你一个起点。

答案 1 :(得分:34)

您可以使用Pattern / Matcher。来自Matcher javadocs:

 Pattern p = Pattern.compile("cat");
 Matcher m = p.matcher("one cat two cats in the yard");
 StringBuffer sb = new StringBuffer();
 while (m.find()) {
     m.appendReplacement(sb, "dog");
 }
 m.appendTail(sb);
 System.out.println(sb.toString());

答案 2 :(得分:12)

查看 String 类的 replaceAll 方法的JavaDoc:

  

替换此字符串中与给定常规匹配的每个子字符串   表达式与给定的替换。调用此方法   str.replaceAll(regex,repl)形式的结果完全相同   作为表达式

     

<强> java.util.regex.Pattern.compile(正则表达式).matcher(STR).replaceAll(REPL)

如您所见,您可以使用模式匹配来执行此操作。

答案 3 :(得分:12)

@Adam:我认为在你的代码片段中你应该跟踪m.find()的起始位置,因为字符串替换可能会在最后一个字符匹配后更改偏移量。

public static void replaceAll(StringBuilder sb, Pattern pattern, String replacement) {
    Matcher m = pattern.matcher(sb);
    int start = 0;
    while (m.find(start)) {
        sb.replace(m.start(), m.end(), replacement);
        start = m.start() + replacement.length();
    }
}

答案 4 :(得分:11)

org.apache.commons.lang3.text.StrBuilder中的课程Apache Commons Lang允许替换:

public StrBuilder replaceAll(String searchStr, String replaceStr)

* 这不会收到正则表达式,而是一个简单的字符串。

答案 5 :(得分:6)

即使是简单的也使用String ReplaceAll函数本身。你可以把它写成

StringBuilder sb = new StringBuilder("Hi there, are you there?")
System.out.println(Pattern.compile("there").matcher(sb).replaceAll("niru"));

答案 6 :(得分:2)

java.util.regex.Pattern.matcher(CharSequence s)可以使用StringBuilder作为参数,这样您就可以使用start()和end()查找和替换模式的每个出现,而无需调用builder.toString()

答案 7 :(得分:2)

使用以下内容:

/**
* Utility method to replace the string from StringBuilder.
* @param sb          the StringBuilder object.
* @param toReplace   the String that should be replaced.
* @param replacement the String that has to be replaced by.
* 
*/
public static void replaceString(StringBuilder sb,
                                 String toReplace,
                                 String replacement) {      
    int index = -1;
    while ((index = sb.lastIndexOf(toReplace)) != -1) {
        sb.replace(index, index + toReplace.length(), replacement);
    }
}

答案 8 :(得分:1)

这是一个原位replaceAll,它将修改传入的StringBuilder。我以为我会发布这个,因为我想用replaceAll来创建一个新的String。

public static void replaceAll(StringBuilder sb, Pattern pattern, String replacement) {
    Matcher m = pattern.matcher(sb);
    while(m.find()) {
        sb.replace(m.start(), m.end(), replacement);
    }
}

令我感到震惊的是,执行此操作的代码有多简单(出于某种原因,我认为在使用匹配器时更改StringBuilder会抛出组的开始/结束,但事实并非如此)。

这可能比其他正则表达式的答案更快,因为模式已经编译,你没有创建新的字符串,但我没有做任何基准测试。

答案 9 :(得分:1)

如何创建方法并让String.replaceAll为您完成:

public static void replaceAll(StringBuilder sb, String regex, String replacement)
{
    String aux = sb.toString();
    aux = aux.replaceAll(regex, replacement);
    sb.setLength(0);
    sb.append(aux);     
}

答案 10 :(得分:1)

是。使用 String.replaceAll() 方法非常简单:

package com.test;

public class Replace {

    public static void main(String[] args) {
        String input = "Hello World";
        input = input.replaceAll("o", "0");
        System.out.println(input);
    }
}

输出:

Hell0 W0rld

如果您真的想使用 StringBuilder.replace(int start, int end, String str) ,那么请转到此处:

public static void main(String args[]) {
    StringBuilder sb = new StringBuilder("This is a new StringBuilder");

    System.out.println("Before: " + sb);

    String from = "new";
    String to = "replaced";
    sb = sb.replace(sb.indexOf(from), sb.indexOf(from) + from.length(), to);

    System.out.println("After: " + sb);
}

输出:

Before: This is a new StringBuilder
After: This is a replaced StringBuilder

答案 11 :(得分:0)

public static String replaceCharsNew(String replaceStr,Map<String,String> replaceStrMap){
        StringBuilder replaceStrBuilder = new StringBuilder(replaceStr);
        Set<String> keys=replaceStrMap.keySet();
        for(String invalidChar:keys){
            int index = -1;
            while((index=replaceStrBuilder.indexOf(invalidChar,index)) !=-1){
                replaceStrBuilder.replace(index,index+invalidChar.length(),replaceStrMap.get(invalidChar));
            }
        }
        return replaceStrBuilder.toString();
    }

答案 12 :(得分:0)

我找到了这个方法:Matcher.replaceAll(String replacement); 在java.util.regex.Matcher.java中,您可以看到更多:

 /**
 * Replaces every subsequence of the input sequence that matches the
 * pattern with the given replacement string.
 *
 * <p> This method first resets this matcher.  It then scans the input
 * sequence looking for matches of the pattern.  Characters that are not
 * part of any match are appended directly to the result string; each match
 * is replaced in the result by the replacement string.  The replacement
 * string may contain references to captured subsequences as in the {@link
 * #appendReplacement appendReplacement} method.
 *
 * <p> Note that backslashes (<tt>\</tt>) and dollar signs (<tt>$</tt>) in
 * the replacement string may cause the results to be different than if it
 * were being treated as a literal replacement string. Dollar signs may be
 * treated as references to captured subsequences as described above, and
 * backslashes are used to escape literal characters in the replacement
 * string.
 *
 * <p> Given the regular expression <tt>a*b</tt>, the input
 * <tt>"aabfooaabfooabfoob"</tt>, and the replacement string
 * <tt>"-"</tt>, an invocation of this method on a matcher for that
 * expression would yield the string <tt>"-foo-foo-foo-"</tt>.
 *
 * <p> Invoking this method changes this matcher's state.  If the matcher
 * is to be used in further matching operations then it should first be
 * reset.  </p>
 *
 * @param  replacement
 *         The replacement string
 *
 * @return  The string constructed by replacing each matching subsequence
 *          by the replacement string, substituting captured subsequences
 *          as needed
 */
public String replaceAll(String replacement) {
    reset();
    StringBuffer buffer = new StringBuffer(input.length());
    while (find()) {
        appendReplacement(buffer, replacement);
    }
    return appendTail(buffer).toString();
}