ocaml Str.full_split不返回原始字符串,而不返回预期的子字符串

问题描述

我正在尝试编写一个程序,该程序将读取diff文件并返回文件名,仅返回文件名。所以我写了下面的代码

open Printf
open Str
let syname: string = "diff --git a/drivers/usc/filex.c b/drivers/usc/filex"

let fileb = 
  let pat_filename = Str.regexp "a\/(.+)b" in
  let s = Str.full_split pat_filename syname in
  s

let print_split_res (elem: Str.split_result) =
  match elem with
  | Text t -> print_string t
  | Delim d -> print_string d

let rec print_list (l: Str.split_result list) =
  match l with
  | [] -> ()
  | hd :: tl -> print_split_res hd ; print_string "\n" ; print_list tl
;;

() = print_list fileb

运行此命令后,我得到原始的ing diff --git a/drivers/usc/filex.c b/drivers/usc/filex作为输出

如果我在python标准库中使用相同的regex模式,则会得到所需的结果

import re
p=re.compile('a\/(.+)b')
p.findall("diff --git a/drivers/usc/filex.c b/drivers/usc/filex")

输出['drivers/usc/filex.c ']

我在做什么错了?

解决方法

别客气,但是了解OCaml正则表达式的方法是阅读文档,而不是与另一种语言进行比较:-)遗憾的是,对于跨语言的正则表达式没有真正的标准。

主要问题似乎是OCaml正则表达式中的括号相互匹配。要获得分组行为,必须使用'\\'对其进行转义。换句话说,您的模式正在文件名中寻找实际的括号。如果将正则表达式更改为以下代码,则您的代码对我有用:

Str.regexp "a/\\(.+\\)b"

请注意,反斜杠本身必须转义,以便Str.regexp能够看到它们。

您还遇到一个问题,就是您的模式与b之后的斜杠不匹配。因此,结果文本将以斜杠开头。

作为补充,我还删除了/之前的反斜杠,这在OCaml字符串中在技术上是不允许的。