Я что-то упускаю, или у StringBuilder нет такой же "замены всех вхождений строки A со строкой B", что и обычный класс String? Функция замены StringBuilder не совсем то же самое. Есть ли способ сделать это более эффективно, не генерируя несколько строк, используя обычный класс String?
Заменить все вхождения строки с помощью StringBuilder?
Ответ 1
Ну, вы можете написать цикл:
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
, работая со спины. Я подозреваю, что случай, если вы заменяете длинную строку коротким - поэтому, когда вы дойдете до начала, любые замены имеют меньше, чем копировать. В любом случае, это должно дать вам отправную точку.
Ответ 2
Вы можете использовать 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());
Ответ 3
Посмотрите на метод JavaDoc replaceAll класса String:
Заменяет каждую подстроку этой строки, которая соответствует данному регулярному выражение с данной заменой. Вызов этого метода формы str.replaceAll(regex, repl) дает точно такой же результат как выражение
java.util.regex.Pattern.compile(регулярное выражение).matcher(ул).replaceAll(REPL)
Как вы можете видеть, вы можете использовать Шаблон и Матчи.
Ответ 4
Класс org.apache.commons.lang3.text.StrBuilder
в Apache Commons Lang позволяет заменять:
public StrBuilder replaceAll(String searchStr, String replaceStr)
* Это не получает регулярное выражение, а просто строку.
Ответ 5
@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();
}
}
Ответ 6
Даже простая использует сама функция String ReplaceAll. Вы можете записать его как
StringBuilder sb = new StringBuilder("Hi there, are you there?")
System.out.println(Pattern.compile("there").matcher(sb).replaceAll("niru"));
Ответ 7
java.util.regex.Pattern.matcher(CharSequence s) может использовать StringBuilder в качестве аргумента, чтобы вы могли находить и заменять каждый появление вашего шаблона с использованием start() и end() без вызова builder.toString()
Ответ 8
Используйте следующее:
/**
* 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);
}
}
Ответ 9
Вот на месте replaceAll, который изменит переданный в StringBuilder. Я думал, что я опубликую это, поскольку я искал сделать 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);
}
}
Я был шокирован тем, насколько простым был код, чтобы сделать это (по какой-то причине я думал, что изменение StringBuilder при использовании совпадения будет включать начало/конец группы, но это не так).
Это, вероятно, быстрее, чем другие ответы в регулярном выражении, потому что шаблон уже скомпилирован, и вы не создаете новую строку, но я не делал никаких бенчмаркинга.
Ответ 10
Как создать метод и 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);
}
Ответ 11
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
Я нашел этот метод: Matcher.replaceAll (замена строки); В 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 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();
}
Ответ 13
Да. Использовать 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