F# F中的模式匹配问题#

F# F中的模式匹配问题#,f#,F#,我需要在F#的Patrenmatch方面得到帮助。 我想这样做: let y x = match x with | x.Contains("hi") -> "HELLO" | x.Contains("hello") -> "HI" | x -> x 但它不起作用。怎么了?最简单的方法是在比赛中使用when后卫 let y (x:string) = mat

我需要在F#的Patrenmatch方面得到帮助。 我想这样做:

            let y x =
            match x with
            | x.Contains("hi") -> "HELLO"
            | x.Contains("hello") -> "HI"
            | x -> x

但它不起作用。怎么了?

最简单的方法是在比赛中使用when后卫

let y (x:string) =
  match x with
  | x when x.Contains("hi") -> "HELLO"
  | x when x.Contains("hello") -> "HI"
  | x -> x

包含方法调用的条件只能在pblasucci写入时在
保护中写入

如果您想使用一些高级F#功能(例如,如果您需要经常编写此功能),则可以定义活动模式来检查子字符串(但如果您只是在学习F#,则不要担心这一点):

然后您可以编写这样的内容(有趣的是,您也可以使用嵌套模式检查多个单词,但同样的内容可以使用
&
模式编写):

我想我对前一个问题的回答可能会帮助您更好地理解模式匹配

但是,对于您试图做的事情,我可能会坚持使用简单的if/then/else表达式:

let y x =
  if x.Contains("hi") then "HELLO"
  elif x.Contains("hello") then "HI"
  else x
创建一个特殊的
Contains
活动模式,比如@Tomas Petricek shows,也是一个选项,但我发现如果我真的要做一些严肃的字符串模式匹配,那么我只需要使用几个忠实的正则表达式活动模式:

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
对于这个问题,请像这样使用它们:

let y = function // shorthand for let y x = match x with ...
    | CompiledMatch @"hi" _ -> "HELLO"
    | CompiledMatch @"hello" _ -> "HI"
    | x -> x
我喜欢这个,因为它轻松地涵盖了Contains、StartsWith、EndsWith、Equals和beyond:

let y = function
    | CompiledMatch @"^hi$" _ -> "Equals"
    | CompiledMatch @"^hi" _ -> "StartsWith"
    | CompiledMatch @"hi$" _ -> "EndsWith"
    | CompiledMatch @"leadinghiending" _ -> "Beyond"
    | CompiledMatch @"hi" _ -> "Contains"
    | x -> x

(请注意,由@引入的文本字符串实际上并不需要用于这些正则表达式示例,但作为一种习惯,我总是使用它们,因为正则表达式更需要它们)。

谢谢!当带有If
CompiledMatch
的x.contains(“hello”)被以某种方式记录下来,这样编译后的正则表达式就可以在后续调用中以相同的模式重复使用时,我想这会更好。如果您只是想扔掉已编译的Regex对象,每次都重新创建它,那么
解释器匹配
@Joel Mueller可能会获得更好的性能,但事实确实如此!Match缓存它用来构造匹配实例的已解析和编译的正则表达式模式,请参见和
let y = function // shorthand for let y x = match x with ...
    | CompiledMatch @"hi" _ -> "HELLO"
    | CompiledMatch @"hello" _ -> "HI"
    | x -> x
let y = function
    | CompiledMatch @"^hi$" _ -> "Equals"
    | CompiledMatch @"^hi" _ -> "StartsWith"
    | CompiledMatch @"hi$" _ -> "EndsWith"
    | CompiledMatch @"leadinghiending" _ -> "Beyond"
    | CompiledMatch @"hi" _ -> "Contains"
    | x -> x