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