假设我有一个字符串:
"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
或者还有其他我不知道的方式?
简单的方法:让我们继续拆分我们想要拆分的空白字符,使用
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"]