2

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?

3
  • The trouble is that $? isn't a regex pattern. What is the pattern in fact and are both patterns the same? Commented Aug 24, 2021 at 7:51
  • We can change the pattern to some other valid regex pattern too. However, how to replace that pattern at multiple places with different values? Commented Aug 24, 2021 at 7:55
  • Well you didn't answer whether they are the same value. It seems to me that they might be placeholders and not patterns Commented Aug 24, 2021 at 7:59

4 Answers 4

2

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?
Sign up to request clarification or add additional context in comments.

Comments

1

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.

5 Comments

Is it possible to pass as an array of values and replace the same in a single line?
you can call replaceOnce in loop on array
@Vishal: see edited answer, found a way to do it in one line
Since the placeholder is same ($?) at both the places, same value is getting replaced. Its resulting in "HithereHellothere" and not "HithereHelloworld"
@Vishal, you are right. so loop on replacement array and calling replaceOnce() seems inevitable
0

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();
}

2 Comments

FYI, StringUtils.replaceEach is using StringBuilder
@SharonBenAsher yes, I forgot about this.
0

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);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.