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

时间:2013-12-01 04:55:29

标签: string replace f#

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的状态。什么是正确的方法?

3 个答案:

答案 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