Search code examples
javaregexregexp-replace

Swap two specific words using regex


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?


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.