I need your help for one tricky problem. I have one map like below
Map<Integer, String> ruleMap = new HashMap<>();
ruleMap.put(1, "A");
ruleMap.put(12, "Test - 12");
ruleMap.put(1012, "Test Metadata 12 A");
and I have one rule in which I am separating ids and collecting them into a list. By iterating over the list, I am replacing its ids by its respective value from map.
code :
String rule = "1 AND 12 OR 1012 AND 12 or 1012";
List < String > idList = new ArrayList < > ();
Pattern p = Pattern.compile("[0-9]+");
Matcher m = p.matcher(rule);
while (m.find()) {
idList.add(m.group());
}
for (String id: idList) {
if (ObjectUtils.isNonEmpty(ruleMap.get(Integer.parseInt(id)))) {
rule = rule.replaceFirst(id, ruleMap.get(Integer.parseInt(id)));
}
}
System.out.println(rule);
I am getting output like this -
A AND Test - Test - 12 OR Test Metadata 12 A AND 12 or Test Metadata 12 A
as you can see for the first iteration of id 12
replaced its respected value but on the second occurrence of the id 1
2 replaced the value Test - 12
to Test - Test - 12
.
So can anyone help me with this?
You need to be doing regex replacement with proper word boundaries. I suggest using a regex iterator (as you were already doing), but use the pattern \\b\\d+\\b
to match only full number strings. Then, at each match, do a lookup in the rule map, if the number be present, to find a replacement value. Use Matcher#appendReplacement
to build out the replacement string as you go along.
Map<String, String> ruleMap = new HashMap<>();
ruleMap.put("1", "A");
ruleMap.put("12", "Test - 12");
ruleMap.put("1012", "Test Metadata 12 A");
String rule = "1 AND 12 OR 1012 AND 12 or 1012";
Pattern pattern = Pattern.compile("\\b\\d+\\b");
Matcher m = pattern.matcher(rule);
StringBuffer buffer = new StringBuffer();
while(m.find()) {
if (ruleMap.containsKey(m.group(0))) {
m.appendReplacement(buffer, ruleMap.get(m.group(0)));
}
}
m.appendTail(buffer);
System.out.println(rule + "\n" + buffer.toString());
This prints:
1 AND 12 OR 1012 AND 12 or 1012
A AND Test - 12 OR Test Metadata 12 A AND Test - 12 or Test Metadata 12 A
If you happen to use Java 9 or higher you could also use Matcher#replaceAll
:
Map<Integer, String> ruleMap = new HashMap<>();
ruleMap.put(1, "A");
ruleMap.put(12, "Test - 12");
ruleMap.put(1012, "Test Metadata 12 A");
String rule = "1 AND 12 OR 1012 AND 12 or 1012";
rule = Pattern.compile("\\b\\d+\\b")
.matcher(rule)
.replaceAll(m -> ruleMap.getOrDefault(
Integer.parseInt(m.group()), m.group()));
System.out.println(rule);
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.