2011-12-30 40 views
2

如何在Ocaml中使用正則表達式來查找精確匹配?例如,我有一個這樣的代碼:使用正則表達式在Ocaml中匹配確切的字符串

let contains s1 s2 = 
let re = Str.regexp_string s2 
in 
try ignore (Str.search_forward re s1 0); true 
with Not_found -> false 

其中s2爲「_X_1」和S1像「A_1_X_1」,「A_1_X_2」,飼料串....等的功能「包含」。目標是在s1爲「A_1_X_1」時找到完全匹配。但是當前的代碼甚至在s1是「A_1_X_10」,「A_1_X_11」,「A_1_X_100」等時找到匹配。

我試着用「[_x_1]」,「[_X_1] $」作爲s2而不是「_X_1」,但似乎沒有工作。有人可以建議什麼是錯的?

+1

您使用'Str.regexp_string'產生,從字面上傳遞的字符串相匹配的正則表達式,而不用解釋元字符。 – 2011-12-30 13:15:53

+0

是的,你是對的馬蒂亞斯。還包含「A_1_X_1」「_X_1 $」返回false – 2011-12-30 13:18:14

+0

是的,我希望如果我們將「_X_1」傳遞給它,Str.regexp_string將返回^ _X_1 $。因此我的代碼就是這樣寫的。但Str.regexp_string正在做別的... – 2011-12-30 13:22:39

回答

3

可以使用$元字符到行的末尾匹配(其,假設字符串doens不包含多行,則是字符串的結尾)。但是你不能通過Str.regexp_string;這只是逃避了元字符。你應該先引用實際子部分,然後追加$,然後進行從一個正則表達式:

let endswith s1 s2 = 
    let re = Str.regexp (Str.quote s2^"$") 
    in 
    try ignore (Str.search_forward re s1 0); true 
    with Not_found -> false 
+0

是的,你是對的。我使用regexp_string犯了一個錯誤。我應該使用正則表達式。感謝您的投入! – 2012-01-02 10:37:58

0

正則表達式將匹配輸入中的任何位置,因此您看到的行爲是正常的。

你需要錨定你的正則表達式:^_X_1$

此外,[_x_1]不會幫助:[...]是一個字符類,在這裏你問的正則表達式引擎匹配的字符是x1_

+0

與^ _X_1 $,它甚至不匹配_X_1。它也會爲_X_1返回false – 2011-12-30 12:25:43

+0

Eh?那是什麼正則表達式引擎? – fge 2011-12-30 12:26:38

+0

嗯,我是Ocaml的新手,對此不太瞭解。但我最初的預感是轉換爲正則表達式本身正在做一些奇怪的事情。 (Str.regexp_string) – 2011-12-30 13:13:15

2

Str.match_end是你所需要的:

let ends_with patt str = 
    let open Str in 
    let re = regexp_string patt in 
    try 
    let len = String.length str in 
    ignore (search_backward re str len); 
    match_end() == len 
    with Not_found -> false 

根據這個定義,函數工作,你需要:

# ends_with "_X_1" "A_1_X_10";; 
- : bool = false 
# ends_with "_X_1" "A_1_X_1";; 
- : bool = true 
# ends_with "_X_1" "_X_1";; 
- : bool = true 
# ends_with "_X_1" "";; 
- : bool = false 
+0

謝謝Matias的輸入! – 2011-12-30 13:26:01