Java Replacing Multiple Different Substring in a String at Once (Or in the Most Efficient Way)

Java Replacing multiple different substring in a string at once (or in the most efficient way)

If the string you are operating on is very long, or you are operating on many strings, then it could be worthwhile using a java.util.regex.Matcher (this requires time up-front to compile, so it won't be efficient if your input is very small or your search pattern changes frequently).

Below is a full example, based on a list of tokens taken from a map. (Uses StringUtils from Apache Commons Lang).

Map<String,String> tokens = new HashMap<String,String>();
tokens.put("cat", "Garfield");
tokens.put("beverage", "coffee");

String template = "%cat% really needs some %beverage%.";

// Create pattern of the format "%(cat|beverage)%"
String patternString = "%(" + StringUtils.join(tokens.keySet(), "|") + ")%";
Pattern pattern = Pattern.compile(patternString);
Matcher matcher = pattern.matcher(template);

StringBuffer sb = new StringBuffer();
while(matcher.find()) {
matcher.appendReplacement(sb, tokens.get(matcher.group(1)));
}
matcher.appendTail(sb);

System.out.println(sb.toString());

Once the regular expression is compiled, scanning the input string is generally very quick (although if your regular expression is complex or involves backtracking then you would still need to benchmark in order to confirm this!)

Replacing multiple substrings from a string in Java/Android

You can create a function like below:

String replaceMultiple (String baseString, String ... replaceParts) {
for (String s : replaceParts) {
baseString = baseString.replaceAll(s, "");
}
return baseString;
}

And call it like:

String finalString = replaceMultiple("This is just a string folks", "This is", "folks");

You can pass multiple strings that are to be replaced after the first parameter.

Replace multiple substrings at once

This is how your Python-suggestion translates to Java:

Map<String, String> replacements = new HashMap<String, String>() {{
put("substr1", "repl1");
put("substr2", "repl2");
put("substr3", "repl3");
}};

String input = "lorem substr1 ipsum substr2 dolor substr3 amet";

// create the pattern joining the keys with '|'
String regexp = "substr1|substr2|substr3";

StringBuffer sb = new StringBuffer();
Pattern p = Pattern.compile(regexp);
Matcher m = p.matcher(input);

while (m.find())
m.appendReplacement(sb, replacements.get(m.group()));
m.appendTail(sb);

System.out.println(sb.toString()); // lorem repl1 ipsum repl2 dolor repl3 amet

This approach does a simultanious (i.e. "at once") replacement. I.e., if you happened to have

"a" -> "b"
"b" -> "c"

then this approach would give "a b" -> "b c" as opposed to the answers suggesting you should chain several calls to replace or replaceAll which would give "c c".


(If you generalize this approach to create the regexp programatically, make sure you Pattern.quote each individual search word and Matcher.quoteReplacement each replacement word.)

Replacing multiple substrings in Java when replacement text overlaps search text

It seems StringUtils.replaceEach in apache commons does what you want:

StringUtils.replaceEach("abcdeab", new String[]{"ab", "cd"}, new String[]{"cd", "ab"});
// returns "cdabecd"

Note that the documenent at the above links seems to be in error. See comments below for details.

Replacing a set substrings in a string independently (parallel)

You better use a map and iterate over every character in template. This way you avoid multiple substitutions at the same index position.

String template = "abcd";
StringBuilder populatedTemplate = new StringBuilder();
HashMap<Character, Character> map = new HashMap<>();
map.put('a', 'b');
map.put('b', 'c');
for (int i = 0; i < template.length(); i++) {
populatedTemplate.append(
map.getOrDefault(template.charAt(i), template.charAt(i)));
}
System.out.println(populatedTemplate);

Some pro arguments of this solution compared to OPs posted solution.

  • avoid multiple substitutions at the same index position, replace in a first step a to b and in a second step b to c which would lead into an unexpected effective replacement of a to c
  • iterate only once over template
  • don't create for each replacement pair a new String object, as it would have been here p = p.replace(values[i], values[i+1]);

Java: Replace a specific character with a substring in a string at index

String[][] arr = {{"1", "one"}, 
{"5", "five"}};

String str = "String5";
for(String[] a: arr) {
str = str.replace(a[0], a[1]);
}

System.out.println(str);

This would help you to replace multiple words with different text.

Alternatively you could use chained replace for doing this, eg :

str.replace(1, "One").replace(5, "five");

Check this much better approach : Java Replacing multiple different substring in a string at once (or in the most efficient way)



Related Topics



Leave a reply



Submit