2016-01-05 93 views
0

我希望能夠將「你是」,「我是」和「你」等短語替換爲「我的」。如何在保持代碼乾爽的情況下做到這一點?如何迭代字符串並替換某些短語?

到目前爲止,我有這樣的事情......

let re = Regex::new(r"you are").unwrap(); 
re.replace_all("you are awesome and so is your hat", "I am") 

但這只是取代了「你」,而不是「我」的一部分。

我認爲理想的,它會看起來像

let re = Regex::new(r"your|you are").unwrap(); 
re.replace_all("you are awesome and so is your hat", fn_with_pattern_matching) 
+0

如何編寫2個單獨的replace_all語句? –

+0

您最後一個帶有'fn_with_pattern_matching'的代碼片段應該可行。請參閱'regex'文檔中的示例:http://doc.rust-lang.org/regex/regex/enum.Regex.html#examples-2您可能需要利用捕獲組來確定將哪些文本儘管用作替代品。 – BurntSushi5

+0

@ BurntSushi5,是啊我試過使用捕獲組,但我有很多理解文檔的麻煩,似乎無法讓它按預期工作 – Vin

回答

1

讓我們先從karthik manchala答案,Shepmaster建議:

發生在陣列中的所有字符串和迭代這個數組。如果你的 應用邏輯是「用B替換所有的A,那麼所有的C都用D,那麼所有的E都用F」,那麼代碼就會反映那個重複的邏輯。

而不是將字符串保留在數組中我建議將編譯的正則表達式存儲在那裏以避免每次重建它們。

下面的代碼:

extern crate regex; 

use regex::Regex; 
use std::env::args; 
use std::iter::FromIterator; 

fn main() { 
    let patterns = [("your", "mine"), ("you are", "I am")]; 
    let patterns = Vec::from_iter(patterns.into_iter().map(|&(k, v)| { 
     (Regex::new(k).expect(&format!("Can't compile the regular expression: {}", k)), 
     v) 
    })); 
    for arg in args().skip(1) { 
     println!("Argument: {}", arg); 
     for &(ref re, replacement) in patterns.iter() { 
      let got = re.replace_all(&arg, replacement); 
      if got != arg { 
       println!("Changed to: {}", got); 
       continue; 
      } 
     } 
    } 
} 

這將是它,但爲了完整起見,我想補充一點,如果你想優越的性能,那麼你可能使用本MARK特徵在PCRE正則表達式引擎(pcre crate)。

隨着MARK和模式這樣

"(?x)^(?: 
    (*MARK:0) first pattern \ 
    | (*MARK:1) second pattern \ 
    | (*MARK:2) third pattern \ 
)" 

可以使用MARK數量進行分類或在您的情況爲指標與替代的數組。這通常比使用多個正則表達式更好,因爲主題字符串只處理一次。

+0

*「因爲主題字符串只處理一次」* - 這也會改變行爲,正確嗎?例如,如果我替換A→BC和B→XY,那麼多個循環與多個匹配的單個循環會產生不同的結果。 – Shepmaster

+1

@Shepmaster這取決於循環是如何實現的,以及正則表達式是什麼。有些情況下行爲會相同,唯一的區別是運行時成本。像往常一樣,開發人員應該明白她在做什麼。我的目標不是寫一本關於正則表達式,'MARK'及其所有細微差別的書,而是簡單地提及這個有價值的工具。 ; ) – ArtemGr

1

你可以做到以下幾點:

let str = "you are awesome and so is your hat"; 
let re = Regex::new(r"you are").unwrap(); 
let re1 = Regex::new(r"your").unwrap(); 
re.replace_all(str, "I am"); 
re1.replace_all(str, "my"); 

編輯:

如果你有很多的短語來代替,創建(「要替換的短語」,「要替換的短語」)的映射並遍歷它以執行上述邏輯。

+0

感謝您的建議,但這不是非常幹,並且不能很好地擴展。我正計劃添加更多的短語替換(例如「I」到「你」等) – Vin

+2

*但這不是非常乾燥* - 將所有字符串放在數組中並遍歷數組。如果您的應用程序邏輯是「用B替換所有A,然後用D替換所有C,然後用F替換全部E」,那麼代碼將反映該重複的邏輯。 – Shepmaster