代码之家  ›  专栏  ›  技术社区  ›  Ulrar

Ocaml中字符串的简单解析

  •  0
  • Ulrar  · 技术社区  · 6 年前

    我不知道最好的方法是什么,所以我想我应该问问。我有这样一句话:

    NAME="/dev/sda" TYPE="disk" MODEL="KINGSTON SV300S3"
    

    (从lsblk获得,有几个选项)我想尽可能简单地提取每个字段。是的,我知道lsblk有一个非常好的--json,但不幸的是,这是最近添加的一个我不能使用的东西,我们有一些非常旧的服务器还在生产中。

    也许用Str和regex?谷歌似乎经常说menhir,我从来没有用过它,但我担心仅仅对于这样的几个变量来说可能有点沉重?

    3 回复  |  直到 6 年前
        1
  •  3
  •   Virgile    6 年前

    Str 可能会做这个把戏,鲜为人知的 Genlex module char 流到令牌流中,您可以更轻松地解析这些令牌流。我认为 lsblk

    let lexer = Genlex.make_lexer [ "=" ]
    
    let test = "NAME=\"/dev/sda\" TYPE=\"disk\" MODEL=\"KINGSTON SV300S3\""
    let test_stream = Stream.of_string test
    let test_stream_token = lexer test_stream
    
    let info =
      let l = ref [] in
      try
        while true do
          let kw = Stream.next test_stream_token in
          let eq = Stream.next test_stream_token in
          let v = Stream.next test_stream_token in
          let kw =
            match kw with Ident s -> s | _ -> failwith "Unrecognized pattern"
          in
          let () = match eq with Kwd "=" -> () | _ -> failwith "Expected '='" in
          let v = match v with String s -> s | _ -> failwith "Expected string" in
          l:=(kw,v)::!l
        done;
        assert false
      with Stream.Failure -> List.rev !l
    

    基本上,主循环认为输入中包含的信息是表单项的序列 <key>="<value>" ,由 -生成lexer。

    [("NAME", "/dev/sda"); ("TYPE", "disk"); ("MODEL", "KINGSTON SV300S3")]

        2
  •  3
  •   octachron    6 年前

    let extract s = Scanf.sscanf s "NAME=%S TYPE=%S MODEL=%S" (fun x y z -> x, y ,z);;
    ;; extract {|NAME="/dev/sda" TYPE="disk" MODEL="KINGSTON SV300S3"|}
    

    产量

    (“/dev/sda”,“磁盘”,“金斯顿SV300S3”)

    一如预期。

        3
  •  0
  •   PatJ    6 年前

    知道了:

    let re = Str.regexp "NAME=\"\\(.*\\)\" TYPE=\"\\(.*\\)\" MODEL=\"\\(.*\\)\"" in
      match Str.string_match re line 0 with
      | false -> [`Null]
      | true  ->
         let name = Str.matched_group 1 line in
         let typ = Str.matched_group 2 line in
         let model = Str.matched_group 3 line in
         Printf.printf "%s, %s, %s\n" name typ model