2012-11-20 123 views
0

说我有字符串“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 

我不知道正则表达式可以帮助我在这里要么?顺便说一句,这不是家庭作业,只是令人讨厌的兴趣。我尝试过使用Google搜索,但不确定如何描述问题。

回答

2

尝试先用其他不会在字符串中任何位置出现的其他字符替换“foo”。然后用“foo”替换“bar”,然后用“bar”替换步骤1中的临时替换。

+0

我是那种类似想法的,但肯定必须有一个更好的方法? – Adam

+0

@Adam你可以编写自己的方法来遍历字符串并搜索要替换的字符。基本上这意味着解析String并将每个单独的字符视为一个标记。 –

+0

@Adam可能有正则表达式和捕获组的解决方案。不过,我只有一个模糊的想法。 –

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"))); 
    } 
}