【问题标题】:How to read lists of numbers from a file using string formats in OCaml如何使用 OCaml 中的字符串格式从文件中读取数字列表
【发布时间】:2019-03-17 04:11:16
【问题描述】:

我想获取文件中特定格式的数字列表。但我没有得到数字列表的任何格式(如 %s %d)。

我的文件包含如下文本:

[1;2] [2] 5
[45;37] [9] 33
[3] [2;4] 1000

我尝试了以下

value split_input str fmt =  Scanf.sscanf str fmt (fun x y z -> (x,y,z));

value rec read_file chin acc fmt =
      try let line = input_line chin in
      let (a,b,c) = split_input line fmt in 
      let acc = List.append acc [(a,b,c)] in
            read_file chin acc fmt
      with 
      [ End_of_file -> do { close_in chin; acc}
      ];

value read_list = 
      let chin = open_in "filepath/filename" in
      read_file chin [] "%s %s %d";

问题在于最后指定的格式。我使用相同的代码从其他文件中获取数据,其中数据的格式为 (string * string * int)。

要重用相同的代码,我必须以字符串形式接收上述文本,然后根据我的要求进行拆分。我的问题是:整数列表是否有像 %s %d 这样的格式,以便我直接从文件中获取列表,而不是编写另一个代码将字符串转换为列表。

【问题讨论】:

    标签: ocaml


    【解决方案1】:

    Scanf 中的列表没有内置说明符。可以使用 %r 说明符将解析委托给自定义扫描仪,但 Scanf 并不是真正为解析复杂格式而设计的:

    let int_list b = Scanf.bscanf b "[%s@]" (fun s ->
      List.map int_of_string @@ String.split_on_char ';' s
    )
    

    然后有了这个int_list解析器,我们就可以写了

    let test = Scanf.sscanf "[1;2]@[3;4]" "%r@%r" int_list int_list (@)
    

    获得

    val 测试:int list = [1; 2; 3; 4]

    正如预期的那样。但同时,使用String.split_on_char 进行拆分更容易。一般来说,解析复杂的格式最好用 正则表达式库、解析器组合库或解析器生成器。

    P.S:你可能应该避免修改后的语法,它已经被废弃了。

    【讨论】:

    • 问题是我是 Ocaml 的新手,我正在使用已开发的代码,该代码是用修改后的代码编写的。如果我在 Ocaml 语法中添加新代码而不是修改后的代码,会有什么问题吗?
    猜你喜欢
    • 1970-01-01
    • 2020-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多