将字符串拆分为包含不大于 n 个字符的字符串的字符串列表
Split string into string list containing strings no greater than n chars
我有一个长字符串,需要将其转换为字符串列表,其中列表中的每个字符串 <= 50 个字符。
此外,我不希望单词被拆分 - 如果第 50 个字符是单词中的一个字母,那么我希望拆分发生在前面的 space。
因此,以下字符串:
什么河流发源于黑森林,流经铁门,流入黑海?
应成为包含以下字符串的字符串列表:
What river rises in the Black Forest, flows
through the Iron Gate, and empties into the Black
Sea?
构建链接到的 example @Carsten,这里有一个生成字符串列表的版本,而不是像链接示例那样将它们全部连接在一起:
let until index (text:string) =
text.[0..index-1]
let from index (text:string) =
text.[index..]
let wrap fullText lineLength =
let untilLineLength = until lineLength
let rec wrapRecursive (text:string) existingLines =
if text.Length <= lineLength then
(List.rev ((text.Trim())::existingLines)) //|> String.concat "\n"
else
let wrapIndex,nextLineIndex =
match (text |> untilLineLength).LastIndexOf(" ") with
| -1 -> lineLength, lineLength
| spaceIndex -> spaceIndex, spaceIndex + 1
((text |> until wrapIndex).Trim())::existingLines |> wrapRecursive (text |> from nextLineIndex)
wrapRecursive fullText List.empty
我在递归基本案例中注释掉了 String.concat
以展示如何轻松地将其转换为输出串联字符串。我的示例也应该是尾递归的,这与链接示例不同,它在递归函数中引入了一个累加器列表。
正在测试:
let fullText = "What river rises in the Black Forest, flows through the Iron Gate, and empties into the Black Sea?"
let lineLength = 50
let res = lineLength |> wrap fullText
printfn "%A" res
输出:
["What river rises in the Black Forest, flows"; "through the Iron
Gate, and empties into the Black"; "Sea?"]
我有一个长字符串,需要将其转换为字符串列表,其中列表中的每个字符串 <= 50 个字符。
此外,我不希望单词被拆分 - 如果第 50 个字符是单词中的一个字母,那么我希望拆分发生在前面的 space。
因此,以下字符串:
什么河流发源于黑森林,流经铁门,流入黑海?
应成为包含以下字符串的字符串列表:
What river rises in the Black Forest, flows
through the Iron Gate, and empties into the Black
Sea?
构建链接到的 example @Carsten,这里有一个生成字符串列表的版本,而不是像链接示例那样将它们全部连接在一起:
let until index (text:string) =
text.[0..index-1]
let from index (text:string) =
text.[index..]
let wrap fullText lineLength =
let untilLineLength = until lineLength
let rec wrapRecursive (text:string) existingLines =
if text.Length <= lineLength then
(List.rev ((text.Trim())::existingLines)) //|> String.concat "\n"
else
let wrapIndex,nextLineIndex =
match (text |> untilLineLength).LastIndexOf(" ") with
| -1 -> lineLength, lineLength
| spaceIndex -> spaceIndex, spaceIndex + 1
((text |> until wrapIndex).Trim())::existingLines |> wrapRecursive (text |> from nextLineIndex)
wrapRecursive fullText List.empty
我在递归基本案例中注释掉了 String.concat
以展示如何轻松地将其转换为输出串联字符串。我的示例也应该是尾递归的,这与链接示例不同,它在递归函数中引入了一个累加器列表。
正在测试:
let fullText = "What river rises in the Black Forest, flows through the Iron Gate, and empties into the Black Sea?"
let lineLength = 50
let res = lineLength |> wrap fullText
printfn "%A" res
输出:
["What river rises in the Black Forest, flows"; "through the Iron Gate, and empties into the Black"; "Sea?"]