我有这个代码:
let main argv = let x="b" match x with | _ when Regex.Match(x,"a").Success=true-> let a=Regex.Match(x,"a") Console.WriteLine(a.Groups.[0]) | _ when Regex.Match(x,"b").Success=true-> let b=Regex.Match(x,"b") Console.WriteLine(b.Groups.[0])
我必须在上面的代码中两次写Regex.Match(x,“a”)和Regex.Match(x,“b”).有没有办法只写一次?
解决方法
寻找活跃的模式:
let (|Match|_|) pattern input = let m = Regex.Match(input,pattern,RegexOptions.Singleline) if m.Success then Some (m.Groups.[0]) else None // and use it: match x with | Match @"a text" a -> printfn "found a: %s" a | Match @"b text" b -> printfn "found b: %s" b
您可以更进一步,创建一个支持其自身解析值的活动模式:
let (|Regex|_|) pattern input = let m = Regex.Match(input,RegexOptions.Singleline) if m.Success // List.tail is needed to skip the m.Groups.[0] that returns the entire parsed scope then [ for g in m.Groups -> g.Value ] |> List.tail |> Some else None match x with | Regex @"a (\w+)\s(\w+)" [ a1; a2 ] -> printfn "found A value: %s and %s" a1 a2 | Regex @"b (\w+)\s(\w+)\s(\w+)" [ b1; b2; b3 ] -> printfn "found B value: %s and %s and %s" b1 b2 b3 // this will be able to parse the following: // "a foo bar" ==> a1="foo" and a2="bar" // "b foo bar baz" ==> b1="foo",b2="bar",and b3="baz"