链接字符串.替换在 F# 中



我有一个字符串,里面有一些标记,如下所示:

"There are two things to be replaced.  {Thing1} and {Thing2}"

我想用不同的值替换每个令牌,因此最终结果如下所示:

"There are two things to be replaced.  Don and Jon"

我创建了一个链接字符串的函数。

let doReplacement (message:string) (thing1:string) (thing2:string) =
message.Replace("{Thing1}", thing1).Replace("{Thing2}", thing2)

问题是当我链接.替换时,值必须保持在同一行上。 这样做不起作用:

let doReplacement (message:string) (thing1:string) (thing2:string) =
message
.Replace("{Thing1}", thing1)
.Replace("{Thing2}", thing2)

为了允许我做一个多线链,我想到了这样的事情:

message
|> replaceString "{Thing1}" thing1
|> replaceString "{Thing2}" thing2

具有这样的支持功能:

let replaceString (message:string) (oldValue:string) (newValue:string) =
message.Replace(oldValue, newValue)

但是,这行不通。 有没有其他方法可以处理这个问题?

如果您缩进方法调用,它将编译:

let doReplacement (message:string) (thing1:string) (thing2:string) =
message
.Replace("{Thing1}", thing1)
.Replace("{Thing2}", thing2)

这是我在 C# 中经常看到的一种风格,对我来说似乎很合乎逻辑。

通过使用|>将管道值发送到最右侧的未绑定参数(由|>管道传输的值发送到thing2(。 通过反转参数的顺序,它按预期工作。

let replaceString (oldValue:string) (newValue:string) (message:string) =
message.Replace(oldValue, newValue)
let message = "There are two things to be replaced.  {Thing1} and {Thing2}"
let thing1 = "Don"
let thing2 = "Jon"
message
|> replaceString "{Thing1}" thing1
|> replaceString "{Thing2}" thing2
|> printfn "%s"

您也可以使用折叠来完成此操作(尽管需要在列表/映射中输入。如果你有一致的替换,你会更有用,这可能不适合你(

let replacements =
[ "{thing1}", "Don"
"{thing2}", "Jon" ]
let replaceString (input: string) : string = 
replacements 
|> List.fold (fun acc (oldText, newText) -> acc.Replace(oldText, newText)) input

或者更一般的情况,输入替换作为参数(这次是地图(

let replaceString (replaceMap: Map<string, string>) (input: string) : string =
replaceMap
|> Map.fold (fun acc oldText newText -> acc.Replace(oldText, newText)) input

最新更新