2011-12-30 3 views
2

Как найти точное совпадение с использованием регулярного выражения в Ocaml? Например, у меня есть такой код:Соответствие точной строки в Ocaml с использованием regex

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' который производит регулярное выражение, которое соответствует буквально строке, передаваемой, без интерпретации метасимволы. –

+0

да, вы правы Матиас. Также содержит «A_1_X_1» «_X_1 $» возвращает false –

+0

Да, я надеялся, что Str.regexp_string вернет^_X_1 $, если мы передадим ему «_X_1». Поэтому мой код был написан таким образом. Но Str.regexp_string делает что-то еще ... –

ответ

3

Вы можете использовать $ метасимволы, чтобы соответствовать конец строки (который , предполагая, что строка doens't содержит несколько строк, является концом строки). Но вы не можете это сделать через 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. Я должен был использовать регулярное выражение. Спасибо за вклад! –

0

Регулярное выражение будет соответствовать в любом месте ввода, поэтому поведение, которое вы видите, является нормальным.

Вам необходимо привязать регулярное выражение: ^_X_1$.

Кроме того, [_x_1] не поможет: [...] класс персонажа, здесь вы спросите движок регулярных выражений, чтобы соответствовать символ, который x, 1 или _.

+0

с^_X_1 $, он не совпадает даже с _X_1. он возвращает false для _X_1, а также –

+0

Eh? Что такое двигатель регулярных выражений? – fge

+0

Ну, я новичок в Ocaml и не знаю много об этом. Но моя первоначальная догадка заключается в том, что преобразование в regex само по себе делает что-то странное. (Str.regexp_string) –

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

Спасибо, Матиас за ваш вклад! –

Смежные вопросы