我需要帮助F#中的paternmatching.我想做这个:
let y x =
match x with
| x.Contains("hi") -> "HELLO"
| x.Contains("hello") -> "HI"
| x -> x
Run Code Online (Sandbox Code Playgroud)
但它不起作用.怎么了?
最简单的方法是在匹配情况下使用守卫.
let y (x:string) =
match x with
| x when x.Contains("hi") -> "HELLO"
| x when x.Contains("hello") -> "HI"
| x -> x
Run Code Online (Sandbox Code Playgroud)
包含方法调用的条件只能在whenpblasucci写入时写入保护.
如果你想使用一些高级F#功能(例如,如果你需要写很多),那么你可以定义活动模式来检查子串(但如果你只是学习F#,不要担心这个):
let (|Contains|_|) (what:string) (str:string) =
if str.Contains(what) then Some(str) else None
Run Code Online (Sandbox Code Playgroud)
然后你可以编写类似的东西(有趣的是,你也可以使用嵌套模式检查多个单词,但同样的东西可以使用&模式编写):
match "hello world" with
| Contains "hello" (Contains "world" str) ->
printfn "%s contains both hello and world!" str
| Contains "hello" str ->
printfn "%s contains only hello!" str
| _ -> ()
Run Code Online (Sandbox Code Playgroud)
我想我的答案在这里上一个问题可以帮助你理解模式相匹配的更好一点.
但是,对于你想要做的事情,我可能会坚持使用简单的if/then/else表达式:
let y x =
if x.Contains("hi") then "HELLO"
elif x.Contains("hello") then "HI"
else x
Run Code Online (Sandbox Code Playgroud)
创建一个特殊的Contains活动模式,如@Tomas Petricek节目也是一个选项,但我发现,如果我真的要做一些严肃的字符串模式匹配,那么我只是坚持一些忠实的正则表达式活动模式:
open System.Text.RegularExpressions
///Match the pattern using a cached interpreted Regex
let (|InterpretedMatch|_|) pattern input =
if input = null then None
else
let m = Regex.Match(input, pattern)
if m.Success then Some [for x in m.Groups -> x]
else None
///Match the pattern using a cached compiled Regex
let (|CompiledMatch|_|) pattern input =
if input = null then None
else
let m = Regex.Match(input, pattern, RegexOptions.Compiled)
if m.Success then Some [for x in m.Groups -> x]
else None
Run Code Online (Sandbox Code Playgroud)
对于这个问题,请像这样使用它们:
let y = function // shorthand for let y x = match x with ...
| CompiledMatch @"hi" _ -> "HELLO"
| CompiledMatch @"hello" _ -> "HI"
| x -> x
Run Code Online (Sandbox Code Playgroud)
我喜欢这个,因为它简单地涵盖了Contains,StartsWith,EndsWith,Equals等等:
let y = function
| CompiledMatch @"^hi$" _ -> "Equals"
| CompiledMatch @"^hi" _ -> "StartsWith"
| CompiledMatch @"hi$" _ -> "EndsWith"
| CompiledMatch @"leadinghiending" _ -> "Beyond"
| CompiledMatch @"hi" _ -> "Contains"
| x -> x
Run Code Online (Sandbox Code Playgroud)
(请注意,由@引入的文字字符串实际上并不需要任何这些正则表达式示例,但作为习惯问题,我总是使用它们,因为您经常需要它们而不是正则表达式).