从f#中的字符串中删除字符

deo*_*oll 3 string f# replace

我有一个List<char>stripchars.这些字符不应出现在字符串中text.所以我把它变成了可变的.

所以我做了类似的事情:

stripchars |> Seq.iter(
    fun x ->
        text <- text.Replace(x, ' ')
    )
Run Code Online (Sandbox Code Playgroud)

然后我得到一个错误,说文本是一个以无效方式使用的可变变量.现在我去看看这篇文章,我想出了类似的东西

let s = ref text    
stripchars |> Seq.iter(
    fun ch ->
        printfn "ch: %c" ch
        printfn "resultant: %s" !s
        s :=  (!s).Replace(ch, ' ')
    )
Run Code Online (Sandbox Code Playgroud)

这仍然没有完成变异的状态text.什么是正确的方法?

p.s*_*w.g 6

由于还没有人发布此内容,Core.String模块包含您正在寻找的方法。

要将给定字符替换为空格(或任何其他给定的单个字符),请使用String.map

let strip chars = String.map (fun c -> if Seq.exists((=)c) chars then ' ' else c)

strip "xyz" "123x4y5z789" // 123 4 5 789
Run Code Online (Sandbox Code Playgroud)

要完全删除给定的字符,请使用String.collect

let strip chars = String.collect (fun c -> if Seq.exists((=)c) chars then "" else string c)

strip "xyz" "123x4y5z789" // 12345789
Run Code Online (Sandbox Code Playgroud)


Gen*_*ski 5

由于F#属于.NET堆栈,我们可能依赖于平台库的强大功能. 然后这个字符剥离任务可以实现简单

open System
open System.Linq
let stripChars chars (text:string) = String.Concat(text.Except(stripChars))

更新:不幸的是,后来我意识到Enumerable.Except方法产生了两个序列的集合差异,这意味着stripChars "a" "ababab"它只是"b"预期的而不是预期的"bbb".

在LINQ场所继续,正确工作的实现可能更加冗长:

let stripv1 (stripChars: seq<char>) (text:string) =
    text.Where(fun (c: char) -> not(stripChars.Contains(c))) |> String.Concat    
Run Code Online (Sandbox Code Playgroud)

与等效的惯用语F#相比,这可能不值得付出努力:

let stripv2 (stripChars: seq<char>) text =
    text |> Seq.filter(fun c -> not (stripChars.Contains c)) |> String.Concat
Run Code Online (Sandbox Code Playgroud)

因此,纯粹的.NET特定方法将遵循Ruben关于String.Split以下评论建议:

let stripv3 (stripChars:string) (text:string) =
    text.Split(stripChars.ToCharArray(), StringSplitOptions.RemoveEmptyEntries) |> String.Concat
Run Code Online (Sandbox Code Playgroud)