Reputation: 2066
I am supposed to make a custom decorator so I can replace both in an input from console and from a file:
char[] x = {'a', 'b'}
with char y = '*'
, so both a
and b
become *
char[] x = {'a', 'b'}
with char[] y = {'c', 'd'}
, so a
becomes c
and b
becomes d
What would be the best approach for it? I made the first one with a regular expression ( String replaceAll = s.replaceAll("(a|b)", String.valueOf(replacement));
), but this wouldn't work for the second case. Is there a way to make the second case in one regex? Should I do a HashMap ?
Upvotes: 1
Views: 3412
Reputation: 124225
It would be easier to first create some kind of mapping between replaced character and its replacement. I mean something like
Map<String, String> map = new HashMap<>();
map.put("a", "c");
map.put("b", "d");
then you can use appendReplacement
and appendTail
from Matcher class to replace matched character. Deciding on how to get replaced character can be done like map.get(matchedCharacter)
.
Map<String, String> map = new HashMap<>();
map.put("a", "c");
map.put("b", "d");
String demo = "abcdef";
Pattern p = Pattern.compile("[ab]");
Matcher m = p.matcher(demo);
StringBuffer sb = new StringBuffer();
while (m.find()){
m.appendReplacement(sb, map.get(m.group()));
}
m.appendTail(sb);
String replaced = sb.toString();
System.out.println(replaced);
Output: cdcdef
In below template we usually change only one thing, decision about what to use as replacement of founded match.
StringBuffer sb = new StringBuffer();
while (m.find()){
m.appendReplacement(sb, /* decision about replacement*/ );
// ^^^^^^^^^^^^^^^^^^^^^^^^^^
}
m.appendTail(sb);
String replaced = sb.toString();
So since rest of that logic is repeated, this template was wrapped as String replaceAll(Function<MatchResult,String> replacer)
which require from us to provide logic of obtaining replacement for founded match. So above code can be reduced to:
Map<String, String> map = new HashMap<>();
map.put("a", "c");
map.put("b", "d");
String demo = "abcdef";
Pattern p = Pattern.compile("[ab]");
Matcher m = p.matcher(demo);
String replaced = m.replaceAll(match -> map.get(match.group()));
System.out.println(replaced);
Upvotes: 2
Reputation: 42030
There is a more faster way:
public static void main(String[] args) {
String target = "ab";
String replacement = "**";
char[] array = "abcde".toCharArray();
for (int i = 0; i < array.length; i++) {
int index = target.indexOf(array[i]);
if (index != -1) {
array[i] = replacement.charAt(index);
}
}
System.out.println(array);
}
Upvotes: 1
Reputation: 2687
Here you have, this work 100% right for any example ....
public static void main(String[] args) {
String test = "My name is Baba";
Character[] x = { 'a', 'b' };
StringBuilder sb = new StringBuilder();
sb.append("(");
for (int i = 0; i < x.length; i++) {
if (i == (x.length - 1)) {
sb.append(x[i] + ")");
} else {
sb.append(x[i] + "|");
}
}
System.out.println(sb.toString());
Character y = 'c';
Character[] y1 = { 'd', 'e' };
if (y.getClass().isArray()) {
for (int i = 0; i < y1.length; i++) {
test = test.replaceAll(x[i].toString(), y1[i].toString());
}
} else {
test = test.replaceAll(sb.toString(), String.valueOf(y.toString()));
}
System.out.println(test);
}
Upvotes: 1
Reputation: 41838
DjMike,
For the second one, what would be helpful during the replacement is to call a method that you infuse with the logic to replace different characters with different strings.
PHP has a great facility that does just this called preg_replace_callback(). The linked answer is to a question about the Java equivalent of preg_replace_callback()
Upvotes: 1