Replacing multiple substrings in Java when replacement text overlaps search text

前端 未结 5 712
囚心锁ツ
囚心锁ツ 2021-01-12 20:54

Say you have the following string:

cat dog fish dog fish cat

You want to replace all cats with dogs, all do

5条回答
  •  一向
    一向 (楼主)
    2021-01-12 21:24

    Here's a method to do it without regex.

    I noticed that every time a part of the string a gets replaced with b, b will always be part of the final string. So, you can ignore b from the string from then on.

    Not only that, after replacing a with b, there will be a "space" left there. No replacement can take place across where b is supposed to be.

    These actions add up to look a lot like split. split up the values (making the "space" in between strings), do further replacements for each string in the array, then joins them back.

    For example:

    // Original
    "cat dog fish dog fish cat"
    
    // Replace cat with dog
    {"", "dog fish dog fish", ""}.join("dog")
    
    // Replace dog with fish
    {
        "",
        {"", " fish ", " fish"}.join("fish")
        ""
    }.join("dog")
    
    // Replace fish with cat
    {
        "",
        {
            "",
            {" ", " "}.join("cat"),
            {" ", ""}.join("cat")
        }.join("fish")
        ""
    }.join("dog")
    

    So far the most intuitive way (to me) is to do this is recursively:

    public static String replaceWithJointMap(String s, Map map) {
        // Base case
        if (map.size() == 0) {
            return s;
        }
    
        // Get some value in the map to replace
        Map.Entry pair = map.entrySet().iterator().next();
        String replaceFrom = (String) pair.getKey();
        String replaceTo = (String) pair.getValue();
    
        // Split the current string with the replaceFrom string
        // Use split with -1 so that trailing empty strings are included
        String[] splitString = s.split(Pattern.quote(replaceFrom), -1);
    
        // Apply replacements for each of the strings in the splitString
        HashMap replacementsLeft = new HashMap<>(map);
        replacementsLeft.remove(replaceFrom);
    
        for (int i=0; i

    I don't think this is very efficient though.

提交回复
热议问题