OCaml re2在多行字符串上

时间:2017-03-27 13:20:49

标签: ocaml re2

我只是尝试使用re2替换文件中的正则表达式,测试是为一个简单的字符串传递的。

# module Re2 = Re2.Std.Re2;;
# let re = Re2.create_exn "<key>Tags.*<\\/array>" ;;
# let orig =  "abc <key>Tags</key><array><string>OCaml</string></array> end";;
# Re2.replace_exn ~f:(fun _ -> "<key>Tags</key><array/>") re orig;;
- : string = "abc <key>Tags</key><array/> end"

但是,当我将内容作为ss.xml添加到文件中时:

<key>Starred</key>
<false/>
<key>Tags</key>
<array>
    <string>Think</string>
    <string>Performance Test</string>
    <string>Racket</string>
    <string>OCaml</string>
</array>
<key>Time Zone</key>
<string>Asia/Shanghai</string>

OCaml源代码:

open Core.Std
open Async.Std

module Re2 = Re2.Std.Re2

let trans_reg (input: string) : string =
  let re = Re2.create_exn "<key>Tags.*<\\/array>" in
  let target = "<key>Tags</key><array/>" in
  Re2.replace_exn ~f:(fun _ -> target) re input

let handle_file (filename: string) =
  let%bind text = Reader.file_contents filename in
  Writer.save (filename ^ ".xml") ~contents:(trans_reg text)

let () =
  Command.(run (async ~summary:"" Spec.empty (fun _ -> handle_file "ss.xml")))

我的新文件ss.xml.xml中没有任何内容会发生变化。

我在想:

  1. 在这种情况下如何正则表达式匹配。
  2. 我们何时应在Match.t中使用replace ~f:(Match.t -> string)的参数? ()

2 个答案:

答案 0 :(得分:2)

Re2有一个选项dot_nl,用于控制.是否与\n匹配。默认情况下,dot_nl为false。您可以使用标记为here的标记语法(?s)<key>Tag.*<\\/array>或通过调用

在OCaml中将其设置为true
Re2.create ~options:[ `Dot_nl true ]

我认为此m标志不相关,因为m控制^$的解释。您的模式不使用^$

此外,强制警告:You cannot parse XML with regex

答案 1 :(得分:0)

默认情况下,Re2会逐行匹配您的正则表达式,这就是您的表达式永远不会匹配的原因。

{{3}}提到了多行匹配的m标记。我不知道JaneStreet对re2的绑定是否允许你设置这样的标志,但这绝对是你在这里寻找的。

我会留意并且我会更新我的答案,我发现有用的东西。