[英]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.如您所见,您可以使用Pattern和Matcher来做到这一点。
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.