OCaml正则表达式并避免"尝试...与"

时间:2015-03-12 00:07:27

标签: string pattern-matching ocaml

我是OCaml的新手。我需要在行字符串中搜索数字。我正在使用Str.search_forward来做到这一点。请参阅下面的代码片段。我编码的是有效的,但是另一个OCaml程序员说使用try ... with是不好的OCaml实践。我可以使用Str.string_match,但是我必须使用该字符的位置迭代字符串中的每个字符以测试匹配。这似乎比我正在做的事情效率低得多。

请告诉我如何在OCaml中使用正则表达式来匹配字符串中的数字而不使用try ... with。谢谢!

let find_page_hdr linestr =
    let r1 = Str.regexp "[0-9]+" in
    let pos =
        try
            Str.search_forward r1 linestr 0
        with Not_found -> -1
    in
    if pos >= 0
    then int_of_string (Str.matched_string linestr)
    else -1;;

2 个答案:

答案 0 :(得分:3)

我认为try ... with是不好的OCaml编程实践。如果将try ... with向外移动一点,您的代码可能会更整洁一些。这样的事情可能会很好:

let find_page_hdr linestr =
    try
        ignore (Str.search_forward (Str.regexp "[0-9]+") linestr 0);
        Some (int_of_string (Str.matched_string linestr))
    with Not_found -> None

您可以使用“本地打开”来消除一些混乱:

let find_page_hdr linestr =
    let open Str in
    try
        ignore (search_forward (regexp "[0-9]+") linestr 0);
        Some (int_of_string (matched_string linestr))
    with Not_found -> None

答案 1 :(得分:2)

首先,关于try ... with不良做法,你的朋友可能提到它主要是依靠类型安全的问题。但是,使用负整数" C风格"更糟糕的是因为它破坏了类型安全并且没有明确定义的语义。

最好在代码中返回option类型而不是-1"特殊值"。

至于你的具体问题,我想你可以在...... Str.split中找到答案。

let get_all_ints s =
  List.map int_of_string (Str.split (Str.regex "[^0-9]+") s);;

这会对你有用吗?