2012-11-20 142 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"))); 
    } 
}