1

I have a string The quick * fox jumps * the * dog and I have an array of strings String[] array = {"brown", "over", "lazy"}.

What is the optimal way to replace all * to strings from array then first * must be replaced to array[0] element, the second * to array[1] etc. Of course solution must allow N replacement for N elements in array.

Pavel_K
  • 10,748
  • 13
  • 73
  • 186

6 Answers6

4
String.format("The quick * fox jumps * the * dog".replace("*", "%s"), array);
> The quick brown fox jumps over the lazy dog

replace * to %s and use String.format with the parameters, this way works.

see more: How to format strings in Java

Pshemo
  • 122,468
  • 25
  • 185
  • 269
chengpohi
  • 14,064
  • 1
  • 24
  • 42
  • Up-vote for being the *simplest* solution, one valid interpretation of "optimal way". – Andreas Jun 10 '17 at 13:35
  • 1
    `replaceAll` uses regex syntax where * has special meaning. We don't need regex here, `replace` method would be better since it doesn't use regex syntax (it automatically escapes it) and also replaces all occurrences of searched string. – Pshemo Jun 10 '17 at 14:24
  • Thanks @Pshemo :) – chengpohi Jun 10 '17 at 14:57
3
for (String x : array) {
    yourString = yourString.replaceFirst("\\*", x);
}
Pshemo
  • 122,468
  • 25
  • 185
  • 269
ollaw
  • 2,086
  • 1
  • 20
  • 33
  • `replaceFirst` is using regex syntax where `*` is metacharacter. To make it literal we need to escape it. – Pshemo Jun 10 '17 at 14:26
3

Use appendReplacement functionality of Java regex library:

StringBuffer res = new StringBuffer();
Pattern regex = Pattern.compile("[*]");
Matcher matcher = regex.matcher("Quick * fox jumps * the * dog");
int pos = 0;
String[] array = {"brown", "over", "lazy"};
while (matcher.find()) {
    String replacement = pos != array.length ? array[pos++] : "*";
    matcher.appendReplacement(res, replacement);
} 
matcher.appendTail(res);

Demo.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • 1
    If `pos == array.length`, then just exit the loop, and `appendTail()` will append the rest. Faster than replacing `*` with `*`. --- Note, it is even allowed to skip a call to `appendReplacement()` during the iteration, e.g. if you skip every even `*`, then result will only replace the odd `*` markers. – Andreas Jun 10 '17 at 13:32
  • 1
    @Andreas I'm sure OP will figure out the details of what happens when there are additional placeholders. I just wanted to show him code that does not crash. – Sergey Kalinichenko Jun 10 '17 at 13:36
1

Write a for-loop iterating over each character in the String The quick * fox jumps * the * dog and every time you encounter *, you pick the next element of the array while maintaining the current index.

String text = "The quick * fox jumps * the * dog";
String[] elements = {"brown", "over", "lazy"};

int idx = 0;
StringBuilder result = new StringBuilder();
for (char c : text.toCharArray()) {
    if (c == '*')
        result.append(elements[idx++]);
    else
        result.append(String.valueOf(c));
}
Luciano van der Veekens
  • 6,307
  • 4
  • 26
  • 30
1

If by "optimal way" you mean performance, then use a loop with indexOf() and build the result using a StringBuilder.

Other answers have already covered "simple" (i.e. less code), if that's what you meant by "optimal way".

String input = "The quick * fox jumps * the * dog";
String[] array = {"brown", "over", "lazy"};

StringBuilder buf = new StringBuilder();
int start = 0;
for (int i = 0, idx; i < array.length; i++, start = idx + 1) {
    if ((idx = input.indexOf('*', start)) < 0)
        break;
    buf.append(input.substring(start, idx)).append(array[i]);
}
String output = buf.append(input.substring(start)).toString();

System.out.println(output);

Output

The quick brown fox jumps over the lazy dog

This code will silently accept too many or too few values in the array.

Andreas
  • 154,647
  • 11
  • 152
  • 247
0

In all cases you need to reconstruct the String, and the best way to do so is to use StringBuilder

Two ways to do so :

First

  • Iterate by characters over the string and add it to the StringBuilder if it's not *
  • If the character is *, add the string at index variable that represents the pointer to the strings array
  • Increase index by 1.

Second

  • Split the original String over * using split() method, this gives you an array of strings of the original String without the *
  • Iterate once over the two arrays at the same time, add the item of the array of splits and then add the corresponding index at the second replacement array.
Mohamed Seif
  • 382
  • 1
  • 3
  • 14