Vishal
Vishal

Reputation: 65

How to replace multiple occurrence of same regex pattern in a String with different values in Java

Consider a sample example as below:

String string = "Hi$?Hello$?". In the string object the "$?" is the regex pattern. The first occurrence of the $? has to replaced with "there" and second occurrence of the $? has to replaced with "world".

How to implement the same using Java? or Is there any methods available in Apache commons StringUtils to implement the same?

Upvotes: 2

Views: 1048

Answers (4)

user4910279
user4910279

Reputation:

I recommend the 3rd solution.

Try this.

public static void main(String[] args) {
    String string = "Hi$?Hello$?";
    String[] rep = {"there", "world"};
    String output = string.replaceFirst(
        "\\$\\?(.*)\\$\\?", rep[0] + "$1" + rep[1]);
    System.out.println(output);
}

output:

HithereHelloworld

Or

static final Pattern PAT = Pattern.compile("\\$\\?");

public static void main(String[] args) {
    String string = "Hi$?Hello$?";
    String[] rep = {"there", "world"};
    int[] i = {0};
    String output = PAT.matcher(string).replaceAll(m -> rep[i[0]++]);
    System.out.println(output);
}

Or

static final Pattern PAT = Pattern.compile("\\$\\?");

public static void main(String[] args) {
    String string = "Hi$?Hello$?";
    List<String> rep = List.of("there", "world");
    Iterator<String> iter = rep.iterator();
    String output = PAT.matcher(string).replaceAll(m -> iter.next());
    System.out.println(output);
}

Upvotes: 0

Sharon Ben Asher
Sharon Ben Asher

Reputation: 14328

if all you need is sequential replacement of some placeholder string in search string, you can use Apache StringUtils :

String string = "Hi$?Hello$?";
String placeHolder = "$?";
String[] replacements = {"there", "world"};
for (String replacement : replacements) {
    string = StringUtils.replaceOnce(string, placeHolder, replacement);
}
System.out.println(string);

that is provided the sequence is known in advance and placeholder is guarenteed to be present.

Upvotes: 1

Oleg Cherednik
Oleg Cherednik

Reputation: 18245

I think that you should not focus on some replaceString methods, because on each iteration you will receive a new string. This is not efficient.

Why don't you use StringBuilder?

public static String replaceRegexp(String str, String placeHolder, String... words) {
    int expectedLength = str.length() - placeHolder.length() * words.length + Arrays.stream(words).mapToInt(String::length).sum();
    StringBuilder buf = new StringBuilder(expectedLength);
    int prv = 0;
    int i = 0;
    int pos;

    while ((pos = str.indexOf(placeHolder, prv)) != -1 && i < words.length) {
        buf.append(str.substring(prv, pos));
        buf.append(words[i++]);
        prv = pos + placeHolder.length();
    }

    return buf.append(str.substring(prv)).toString();
}

Upvotes: 0

Tim Biegeleisen
Tim Biegeleisen

Reputation: 520988

Here is a general approach using a formal Java pattern matcher. We can store the replacement string items in a list, and then iterate the input string matching on \$. For each match, we can replace with one replacement item.

String string = "Hi$?Hello$?";
StringBuffer sb = new StringBuffer();
List<String> replacements = Arrays.asList(new String[] {"there", "world"});
Pattern r = Pattern.compile("\\$");
Matcher m = r.matcher(string);
int counter = 0;

while (m.find()) {
    m.appendReplacement(sb, replacements.get(counter++));
}
m.appendTail(sb);
System.out.println(sb.toString());  // Hithere?Helloworld?

Upvotes: 2

Related Questions