I have a text like this:
boy girl loop for get out boy girl left right
I want to swap boy
and girl
using regex。(Notice:boy
/girl
appears in unordered.)So I write this:
String str = "boy girl loop for get out boy girl left right";
String regex = "(\\bgirl\\b)|(\\bboy\\b)";
System.out.println(str.replaceAll(regex, "$2$1"));
But it doesn't work。Can you tell me why and show the correct solution?
You can use a "callback" in the replacement using Matcher#replaceAll
:
String str = "boy girl loop for get out boy girl left right";
Matcher m = Pattern.compile("\\b(girl)\\b|\\b(boy)\\b").matcher(str);
System.out.println( m.replaceAll(r -> r.group(2) != null ? "girl" : "boy") );
// => girl boy loop for get out girl boy left right
See the Java demo online.
Here, \b(girl)\b|\b(boy)\b
matches a whole word girl
into Group 1 and boy
into Group 2.
The r -> r.group(2) != null ? "girl" : "boy"
replacement checks if Group 2 matched, and if not, the replacement is girl
, else, it is boy
.
There is also a "replace with a dictionary" approach:
String[] find = {"girl", "boy"};
String[] replace = {"boy", "girl"};
Map<String, String> dictionary = new HashMap<String, String>();
for (int i = 0; i < find.length; i++) {
dictionary.put(find[i], replace[i]);
}
String str = "boy girl loop for get out boy girl left right";
Matcher m = Pattern.compile("\\b(?:" + String.join("|", find) + ")\\b").matcher(str);
System.out.println( m.replaceAll(r -> dictionary.get(r.group())) );
// => girl boy loop for get out girl boy left right
See this Java demo.