检查字符串是否以OCaml中的某些文本结尾的最方便方法是什么?

时间:2016-06-16 11:22:58

标签: regex string ocaml

您好我一直在互联网上查找一个好方法来实现"字符串是否以某些文字结尾"在OCaml中,我发现与其他编程语言(如Java)相比,在OCaml中操作字符串并不像我预期的那样简单。

这是我的OCaml代码,使用Str.regexp检查文件名称是否以" .ml "结尾?看看它是否是OCaml脚本文件。它不像我预期的那样工作:

let r = Str.regexp "*\\.ml" in
if (Str.string_match r file 0)
  then
    let _ = print_endline ("Read file: "^full_path) in
    readFile full_path
  else
    print_endline (full_path^" is not an OCaml file")

请注意, readFile 是我自己编写的函数,用于从构造的full_path中读取文件。我总是在输出中得到结果,例如

./utilities/dict.ml is not an OCaml file
./utilities/dict.mli is not an OCaml file
./utilities/error.ml is not an OCaml file
./utilities/error.mli is not an OCaml file

我在OCaml中的正则表达式有什么问题,是否有更好/更简单的代码来检查字符串?

2 个答案:

答案 0 :(得分:5)

首先,您的正则表达式不正确,您在.之前忘记了*,正确的版本是:

let r = Str.regexp {|.*\.ml|}

请注意新字符串文字语法的使用,它允许您以更好的方式编写正则表达式而不需要大量的反斜杠。使用带双引号的常规语法,它应如下所示:

let r = Str.regexp ".*\\.ml"

这个正则表达式并不理想,因为它会与file.mlxfile.ml.something.else等匹配。因此,一个更好的版本,将与所有可能的OCaml源文件名匹配,是

let r = Str.regexp {|.*\.ml[ily]?$|}

您也可以使用标准库中的Filename模块,而不是使用正则表达式,该模块具有check_suffix函数:

let is_ml file = Filename.check_suffix file ".ml"

检查所有可能的扩展程序:

let srcs = [".ml"; ".mli"; ".mly"; ".mll"]
let is_ocaml file = List.exists (Filename.check_suffix file) srcs

答案 1 :(得分:2)

可能你会对两种正则表达式混淆:

  • Glob(如bash或其他贝壳中的正则表达式)
    您知道,*匹配空字符串或此样式中任何字符的序列。
  • Posix(与此案例相同)

您需要仔细检查str的文件 http://caml.inria.fr/pub/docs/manual-ocaml/libref/Str.html

这说 . : Matches any character except newline * : Matches the preceding expression zero, one or several times

你看,str库采用后一种风格。 因此,要定义Str.regexp,您需要编写类似

的内容
let r = Str.regexp ".*\.ml";;
val r : Str.regexp = <abstr>

Str.string_match r "fuga.ml" 0;;
- : bool = true

Str.string_match r "fugaml" 0;;
- : bool = false

Str.string_match r "piyo/null/fuga.ml" 0;;
- : bool = true

如果你想使用glob风格的正则表达式,
你可以使用re

在我看来,您不需要使用正则表达式来解决您的问题 只需通过适当的函数判断输入是否包含子串“.ml”。