List<char>
中有stripchars
。这些字符不应出现在字符串text
中。所以我做了那个可变的。
所以我做了类似的事情:
stripchars |> Seq.iter(
fun x ->
text <- text.Replace(x, ' ')
)
然后我收到错误,说文本是以无效方式使用的可变变量。现在我去看this帖子,然后我出来了
let s = ref text
stripchars |> Seq.iter(
fun ch ->
printfn "ch: %c" ch
printfn "resultant: %s" !s
s := (!s).Replace(ch, ' ')
)
这仍然无法改变text
的状态。什么是正确的方法?
答案 0 :(得分:5)
由于F#属于.NET堆栈,我们可能依赖于平台库的强大功能。 然后这个字符剥离任务可以像
<德尔> open System
德尔>
open System.Linq
let stripChars chars (text:string) = String.Concat(text.Except(stripChars))
更新:不幸的是,稍后我意识到Enumerable.Except method会产生两个序列的设置差异,这意味着stripChars "a" "ababab"
只会"b"
而不是预期的"bbb"
。
继续在LINQ会场中,正确工作的实现可能更加冗长:
let stripv1 (stripChars: seq<char>) (text:string) =
text.Where(fun (c: char) -> not(stripChars.Contains(c))) |> String.Concat
与等效的惯用语F#相比,这可能不值得付出努力:
let stripv2 (stripChars: seq<char>) text =
text |> Seq.filter(fun c -> not (stripChars.Contains c)) |> String.Concat
因此,纯粹的.NET特定方法是遵循以下评论中关于String.Split
的{{3}}建议:
let stripv3 (stripChars:string) (text:string) =
text.Split(stripChars.ToCharArray(), StringSplitOptions.RemoveEmptyEntries) |> String.Concat
答案 1 :(得分:4)
尝试使用Seq.fold
Seq.fold (fun (str: string) chr -> str.Replace(chr, ' ')) "Hello world" stripchars
折叠非常强大。它可以在许多你想要反复改变的情况下使用。
另外,您不想实际删除字符;不只是用空格替换它们?如果是这样,你应该使用它:
let stripchars chars str =
Seq.fold
(fun (str: string) chr ->
str.Replace(chr |> Char.ToUpper |> string, "").Replace(chr |> Char.ToLower |> string, ""))
str chars
此外,此解决方案不区分大小写。
答案 2 :(得分:3)
由于尚无人发布,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
要完全删除给定的字符,请使用String.collect
:
let strip chars = String.collect (fun c -> if Seq.exists((=)c) chars then "" else string c)
strip "xyz" "123x4y5z789" // 12345789