迭代 OCaml 中的拆分字符串

问题描述 投票:0回答:1

假设我有一个字符串:

"ab bc cdv gf
ed    aqb ahf sd
abcdef

我要 a) 将其拆分为

' '
和/或
'\r\n'
,
'\t'
b) 遍历新创建的这些子字符串列表,按分隔符拆分并将每个子字符串与某些条件匹配(例如,只选择以
'a'
开头的单词,又名
["ab", "ahf", "abcdef"]

注意:我们也不能使用

Str
或任何其他附加库。

我想出了一些这样的代码:

let f g =
  String.split_on_char ' ' g
  |> List.iter (fun x -> x);;

很明显,它显示了一个错误。即使它有效,它也不会分裂出

'\r\n'
。我本可以使用
List.iter
而不是
List.map (fun x -> x)
,但我只会得到子字符串的拆分列表(仅按
' '
字符)。那么现在另一个问题:我该如何使用

"match (something?) with
| ..." 

在这种情况下?我看不出在上面的代码中添加 match 的方法。在这种情况下我们是否使用相反的

|>
List.iter
或者还有其他我不知道的方式?

ocaml
1个回答
0
投票

简单的方法:让我们继续拆分我们想要拆分的空白字符,使用

List.concat_map
来维护一个“扁平”列表,然后拒绝空列表。

let s = "ab bc cdv gf ed aqb ahf sd abc\r\ndef" in
let split = String.split_on_char in
split ' ' s 
|> List.concat_map (split '\n')
|> List.concat_map (split '\r') 
|> List.filter ((<>) "")

(* Result:
 * ["ab"; "bc"; "cdv"; "gf"; "ed"; "aqb"; "ahf"; "sd"; "abc"; "def"] 
 *)

您也可以使用您选择的正则表达式库并在

\s+
上拆分,但显然这是不允许的。

您还可以使用左折叠将其分解为一个函数,并将要拆分的字符作为字符串提供。

let split_on delims str =
  String.to_seq delims
  |> Seq.fold_left (fun acc delim -> List.concat_map (String.split_on_char delim) acc) [str]
  |> List.filter ((<>) "")
utop # split_on " \t\r\n" s;;
- : string list =
["ab"; "bc"; "cdv"; "gf"; "ed"; "aqb"; "ahf"; "sd"; "abc"; "def"]
© www.soinside.com 2019 - 2024. All rights reserved.