检查字符串是否以 OCaml 中的某些文本结尾的最方便的方法?
The most convenient way to check if a string ends with some text in OCaml?
您好,我一直在互联网上寻找在 OCaml 中实现 "whether a string ends with certain text" 的好方法,我发现与其他编程语言(如Java.
这是我的 OCaml 代码,使用 Str.regexp 检查 file 名称是否以“.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中读取file。我总是在输出中得到结果,例如
./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 中的正则表达式有什么问题,是否有 better/simpler 用于检查字符串的代码?
首先你的正则表达式不正确,你在*
之前忘记了.
,正确的版本是:
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
您可能对两种风格的正则表达式感到困惑:
- Glob(类似于
bash
或其他 shell 中的正则表达式)
您知道,*
匹配空字符串或此样式中的任何字符序列。
- 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”即可。
您好,我一直在互联网上寻找在 OCaml 中实现 "whether a string ends with certain text" 的好方法,我发现与其他编程语言(如Java.
这是我的 OCaml 代码,使用 Str.regexp 检查 file 名称是否以“.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中读取file。我总是在输出中得到结果,例如
./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 中的正则表达式有什么问题,是否有 better/simpler 用于检查字符串的代码?
首先你的正则表达式不正确,你在*
之前忘记了.
,正确的版本是:
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
您可能对两种风格的正则表达式感到困惑:
- Glob(类似于
bash
或其他 shell 中的正则表达式)
您知道,*
匹配空字符串或此样式中的任何字符序列。 - 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”即可。