I' ve got a String like this:
"[1] ,[2,4], [1,2,3] ,[12,42]..." that has non predictable structure (ie there could be more parentheses or more numbers inside them).
The numbers correspond to a certain id that is contained in a HashMap. For example:
1->Apollo11
2->NewYork12
4-> Hello3
...
42->Joe4
...
How could I substitute the numbers in the string with their corresponding id, without ambiguity? For example if I substitute number by number I could have:
Substitution of 1-> even the 1 belonging to 12 is affected.
If I start from the biggest number, ie 42, when 4 is substituted, even the "4" in Joe4 will be affected.
Thanks for your attention.
Simply replacing occurences of the numbers by the associated names would have several drawbacks as you've already found out:
Apollo 11
and later replace 11
. Thus probably the safest approach would be to split your string at the numbers, iterate over the tokens, replace any numbers and re-join the elements.
Example:
Map<String, String> mapping = ...;
String input = "[1] ,[2,4], [1,2,3] ,[12,42]";
String[] elements = input.split("(?<=\\d++|\\D++)");
StringBuilder result = new StringBuilder();
for( String element : elements ) {
//simple way to get around checking whether an element is a number:
//if there is nothing mapped, use the element itself - this also keeps unmapped numbers
String replacement = mapping.get( element );
result.appdend( replacement != null ? replacement : element );
}
Some words on the regex used to split:
(?<=...)
is a zero-width look behind, ie it matches any position directly before any match of the ...
expression. \\d++|\\D++
matches any sequence of digits or non-digits with a possive quantifier (ie matches as much as possible and doesn't "give back" the match). The entire expression matches the positions right before your numbers and right before anything that's not a number (or in other words: after your numbers).
Here is my solution (not polished, but I hope you get the idea). Due of the absence of lookup values I just replace all values with **value**
as an example:
public static void main(String[] args) {
String input = "[1] ,[2,4], [1,2,3] ,[12,42]...";
int start = -1;
StringBuilder builder = new StringBuilder();
for (int idx = 0; idx < input.length(); idx++) {
char c = input.charAt(idx);
if (start == -1) {
if (Character.isDigit(c)) {
start = idx;
} else {
builder.append(c);
}
} else if (!Character.isDigit(c)) {
builder.append(valueOf(input.substring(start, idx)) + c);
start = -1;
}
}
if (start != -1) {
builder.append(valueOf(input.substring(start, input.length())));
}
System.out.println(builder);
}
private static String valueOf(String num) {
int val = Integer.parseInt(num);
return map.getOrDefault(val,"**" + val + "**");
}
Output:
[**1**] ,[**2**,**4**], [**1**,**2**,**3**] ,[**12**,**42**]...
You have to replace the expression map.getOrDefault(val,"**" + val + "**")
with the reference to your map where the replacement strings are held.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.