您好我一直在互联网上查找一个好方法来实现"字符串是否以某些文字结尾"在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中的正则表达式有什么问题,是否有更好/更简单的代码来检查字符串?
答案 0 :(得分:5)
首先,您的正则表达式不正确,您在.
之前忘记了*
,正确的版本是:
let r = Str.regexp {|.*\.ml|}
请注意新字符串文字语法的使用,它允许您以更好的方式编写正则表达式而不需要大量的反斜杠。使用带双引号的常规语法,它应如下所示:
let r = Str.regexp ".*\\.ml"
这个正则表达式并不理想,因为它会与file.mlx
,file.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)
可能你会对两种正则表达式混淆:
bash
或其他贝壳中的正则表达式)*
匹配空字符串或此样式中任何字符的序列。您需要仔细检查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”。