将字符串拆分为包含不超过n个字符串的字符串的字符串列表

时间:2015-06-05 14:59:49

标签: f#

我有一个长字符串,我需要将其转换为字符串列表,其中列表中的每个字符串都是< = 50个字符。

另外,我不希望分词 - 如果第50个字母是单词中的字母,那么我希望分割发生在前面的空格中。

因此,以下字符串:

什么河流在黑森林中升起,流过铁门,并流入黑海?

应该成为包含以下字符串的字符串列表:

What river rises in the Black Forest, flows 
through the Iron Gate, and empties into the Black 
Sea?

1 个答案:

答案 0 :(得分:2)

建立链接到的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

输出:

  

[“什么河流在黑森林里升起,流动”; “通过铁   门,并流入黑色“;”海?“]