简体   繁体   English

使用 StringBuilder 替换所有出现的字符串?

[英]Replace all occurrences of a String using StringBuilder?

Am I missing something, or does StringBuilder lack the same "replace all occurrences of a string A with string B" function that the normal String class does?我是否遗漏了什么,或者 StringBuilder 是否缺少与普通 String 类相同的“用字符串 B 替换所有出现的字符串 A”功能? The StringBuilder replace function isn't quite the same. StringBuilder 替换函数并不完全相同。 Is there any way to this more efficiently without generating multiple Strings using the normal String class?如果不使用普通的 String 类生成多个 String,有什么方法可以更有效地做到这一点?

Well, you can write a loop:好吧,你可以写一个循环:

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);
    }
}

Note that in some cases it may be faster to use lastIndexOf , working from the back.请注意,在某些情况下,从后面开始使用lastIndexOf可能会更快。 I suspect that's the case if you're replacing a long string with a short one - so when you get to the start, any replacements have less to copy.我怀疑如果你用一个短字符串替换一个长字符串就是这种情况 - 所以当你开始时,任何替换都更少复制。 Anyway, this should give you a starting point.无论如何,这应该给你一个起点。

You could use Pattern / Matcher .您可以使用Pattern / Matcher From the Matcher javadocs:来自 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());

@Adam: I think in your code snippet you should track the start position for m.find() because string replacement may change the offset after the last character matched. @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();
    }
}

Look at JavaDoc of replaceAll method of String class:查看String类的replaceAll方法的 JavaDoc:

Replaces each substring of this string that matches the given regular expression with the given replacement.用给定的替换替换此字符串中与给定正则表达式匹配的每个子字符串。 An invocation of this method of the form str.replaceAll(regex, repl) yields exactly the same result as the expression调用 str.replaceAll(regex, repl) 形式的此方法会产生与表达式完全相同的结果

java.util.regex.Pattern.compile(regex).matcher(str).replaceAll(repl) java.util.regex.Pattern.compile(regex).matcher(str).replaceAll(repl)

As you can see you can use Pattern and Matcher to do that.如您所见,您可以使用PatternMatcher来做到这一点。

The class org.apache.commons.lang3.text.StrBuilder in Apache Commons Lang allows replacements: Apache Commons Lang中的类org.apache.commons.lang3.text.StrBuilder允许替换:

public StrBuilder replaceAll(String searchStr, String replaceStr)

* This does not receive a regular expression but a simple string. *这不接收正则表达式,而是一个简单的字符串。

Even simple one is using the String ReplaceAll function itself.即使是简单的方法也是使用 String ReplaceAll 函数本身。 You can write it as你可以把它写成

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

Yes.是的。 It is very simple to use String.replaceAll() method:使用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);
    }
}

Output:输出:

Hell0 W0rld

If you really want to use StringBuilder.replace(int start, int end, String str) instead then here you go:如果你真的想使用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);
}

Output:输出:

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

java.util.regex.Pattern.matcher(CharSequence s) can use a StringBuilder as an argument so you can find and replace each occurence of your pattern using start() and end() without calling builder.toString() java.util.regex.Pattern.matcher(CharSequence s)可以使用 StringBuilder 作为参数,因此您可以使用 start() 和 end() 查找并替换模式的每个出现,而无需调用 builder.toString()

Use the following:使用以下内容:

/**
* 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);
    }
}

Here is an in place replaceAll that will modify the passed in StringBuilder.这是一个就地 replaceAll,它将修改传入的 StringBuilder。 I thought that I would post this as I was looking to do replaceAll with out creating a new String.我想我会发布这个,因为我希望在不创建新字符串的情况下执行 replaceAll。

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);
    }
}

I was shocked how simple the code to do this was (for some reason I thought changing the StringBuilder while using the matcher would throw of the group start/end but it does not).我很震惊执行此操作的代码是如此简单(出于某种原因,我认为在使用匹配器时更改 StringBuilder 会抛出组的开始/结束,但事实并非如此)。

This is probably faster than the other regex answers because the pattern is already compiled and your not creating a new String but I didn't do any benchmarking.这可能比其他正则表达式答案更快,因为模式已经编译并且您没有创建新的 String 但我没有做任何基准测试。

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();
    }

How about create a method and let String.replaceAll do it for you:如何创建一个方法并让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);     
}

I found this method: Matcher.replaceAll(String replacement);我找到了这个方法:Matcher.replaceAll(String replacement); In java.util.regex.Matcher.java you can see more:在 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();
}

Kotlin Method科特林方法

  fun replaceAllStringBuilder(
        builder: java.lang.StringBuilder,
        from: String,
        to: String
    ) {
        if (!builder.contains(from)||from.isNullOrEmpty()) return
        
            var index = builder.indexOf(from)
            while (index != -1) {
                builder.replace(index, index + from.length, to)
                index += to.length 
                index = builder.indexOf(from, index)
            }
        

    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 替换所有出现的“;;” 在 Java 中的字符串中 - Replace all occurrences of “;;” in a string in Java 使用Java替换所有出现的以特定模式开头的字符串 - Replace all occurrences of a string preceded by specific pattern using java 如何在 java 中使用正则表达式替换标签 &lt;&gt; 中所有出现的字符串 - how to replace all occurrences of a string inside tags <> using regex in java 如何在不使用 replace() 方法、StringBuilder、StringBuffer 或数组的情况下替换字符串中的所有字符? - How to replace all characters in a String without using replace() methods , StringBuilder, or StringBuffer, or Arrays? 使用replaceAll()替换字符串中所有出现的字符 - Use replaceAll() to replace all occurrences of characters in string 有没有办法替换列表变量中所有出现的字符串? - Is there a way to replace all occurrences of a string in a variable of a list? String.replace() 不替换所有出现 - String.replace() not replacing all occurrences 是否可以替换字符串中所有出现的字符,但在第一次和最后一次出现时不同? - Is it possible to replace all occurrences of a char in a string, but differently on first and last occurrences? Java - 使用String而不是StringBuilder的StringBuilder - Java — StringBuilder using String & not StringBuilder 使用正则表达式替换所有奇数出现的子字符串 - Replace all odd occurrences of a substring using regex
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM