循环字符串替换

时间:2012-11-20 03:17:40

标签: java string

假设我有字符串“foo1bar2”,我想替换以与预期输出“bar1foo2”并行执行以下替换。

foo => bar
bar => foo

字符串无法标记,因为子字符串可能在任何地方,任意次出现。

一种天真的方法就是像这样替换,但是它会失败,因为第二次替换会撤消第一次。

String output = input.replace("foo", "bar").replace("bar", "foo");
=> foo1foo2

String output = input.replace("bar", "foo").replace("foo", "bar");
=> bar1bar2

我不确定正则表达式可以帮助我吗?顺便说一句,这不是功课,只是令人讨厌的兴趣。我试过谷歌搜索但不确定如何描述问题。

2 个答案:

答案 0 :(得分:2)

首先尝试将“foo”替换为String中其他任何地方都不会出现的内容。然后将“bar”替换为“foo”,然后用“bar”替换步骤1中的临时替换。

答案 1 :(得分:2)

我实际上更喜欢Code-Guru的答案,但既然你说它只是一种好奇心,这里是一个递归的解决方案。我们的想法是仅隔离您要替换的字符串,并在其余部分进行递归,这样我们就不会意外地替换我们已经做过的事情。现在,如果你的两个规则有一个共同的前缀,你可能需要对规则进行一些排序以获得所需的结果,但是这里有:

public class ParallelReplace
{
    public String replace(String s, Rule... rules)
    {
        return runRule(s, 0, rules);
    }

    private String runRule(String s, int curRule, Rule... rules)
    {
        if (curRule == rules.length)
        {
            return s;
        }
        else
        {
            Rule r = rules[curRule];
            int index = s.indexOf(r.lhs);

            if (index != -1)
            {
                return runRule(s.substring(0, index), curRule + 1, rules) + r.rhs
                        + runRule(s.substring(index + r.rhs.length()), curRule + 1, rules);
            }
            else
            {
                return runRule(s, curRule + 1, rules);
            }
        }
    }

    public static class Rule
    {
        public String lhs;
        public String rhs;

        public Rule(String lhs, String rhs)
        {
            this.lhs = lhs;
            this.rhs = rhs;
        }
    }

    public static void main(String[] args)
    {
        String s = "foo1bar2";
        ParallelReplace pr = new ParallelReplace();

        System.out.println(pr.replace(s, new Rule("foo", "bar"), new Rule("bar", "foo")));
    }
}