0 people like it.

Statically typed regex pattern matching

Active pattern returning list of captured groups with parsing.

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
// Based on http://www.fssnip.net/29/title/Regular-expression-active-pattern

open System.Text.RegularExpressions

let inline (|Parse|_|) (str: string) : 'a option =
    let mutable value = Unchecked.defaultof<'a>
    let result = (^a: (static member TryParse: string * byref< ^a> -> bool) str, &value)
    if result then Some value
    else None

let (|Regex|_|) pattern input =
    let m = Regex.Match(input, pattern)
    if m.Success then Some(List.tail [ for g in m.Groups -> g.Value ])
    else None

//Example:
let phone = "(555) 555-5555"
match phone with
| Regex 
    @"\(([0-9]{3})\)[-. ]?([0-9]{3})[-. ]?([0-9]{4})" 
    [ Parse area; Parse prefix; Parse suffix ] ->
    printfn $"Area: %d{area}, Prefix: %d{prefix}, Suffix: %d{suffix}"
| _ -> 
    printfn "Not a phone number"
namespace System
namespace System.Text
namespace System.Text.RegularExpressions
val str : string
Multiple items
val string : value:'T -> string

--------------------
type string = System.String
type 'T option = Option<'T>
val mutable value : 'a (requires member TryParse)
module Unchecked

from Microsoft.FSharp.Core.Operators
val defaultof<'T> : 'T
val result : bool
type byref<'T> = (# "<Common IL Type Omitted>" #)
type bool = System.Boolean
union case Option.Some: Value: 'T -> Option<'T>
union case Option.None: Option<'T>
Multiple items
type Regex =
  new : pattern:string -> Regex + 2 overloads
  member GetGroupNames : unit -> string[]
  member GetGroupNumbers : unit -> int[]
  member GroupNameFromNumber : i:int -> string
  member GroupNumberFromName : name:string -> int
  member IsMatch : input:string -> bool + 1 overload
  member Match : input:string -> Match + 2 overloads
  member MatchTimeout : TimeSpan
  member Matches : input:string -> MatchCollection + 1 overload
  member Options : RegexOptions
  ...

--------------------
Regex(pattern: string) : Regex
Regex(pattern: string, options: RegexOptions) : Regex
Regex(pattern: string, options: RegexOptions, matchTimeout: System.TimeSpan) : Regex
val pattern : string
val input : string
val m : Match
Regex.Match(input: string, pattern: string) : Match
Regex.Match(input: string, pattern: string, options: RegexOptions) : Match
Regex.Match(input: string, pattern: string, options: RegexOptions, matchTimeout: System.TimeSpan) : Match
property Group.Success: bool with get
Multiple items
module List

from Microsoft.FSharp.Collections

--------------------
type List<'T> =
  | ( [] )
  | ( :: ) of Head: 'T * Tail: 'T list
    interface IReadOnlyList<'T>
    interface IReadOnlyCollection<'T>
    interface IEnumerable
    interface IEnumerable<'T>
    member GetReverseIndex : rank:int * offset:int -> int
    member GetSlice : startIndex:int option * endIndex:int option -> 'T list
    member Head : 'T
    member IsEmpty : bool
    member Item : index:int -> 'T with get
    member Length : int
    ...
val tail : list:'T list -> 'T list
val g : Group
property Match.Groups: GroupCollection with get
property Capture.Value: string with get
val phone : string
Multiple items
active recognizer Regex: string -> string -> string list option

--------------------
type Regex =
  new : pattern:string -> Regex + 2 overloads
  member GetGroupNames : unit -> string[]
  member GetGroupNumbers : unit -> int[]
  member GroupNameFromNumber : i:int -> string
  member GroupNumberFromName : name:string -> int
  member IsMatch : input:string -> bool + 1 overload
  member Match : input:string -> Match + 2 overloads
  member MatchTimeout : TimeSpan
  member Matches : input:string -> MatchCollection + 1 overload
  member Options : RegexOptions
  ...

--------------------
Regex(pattern: string) : Regex
Regex(pattern: string, options: RegexOptions) : Regex
Regex(pattern: string, options: RegexOptions, matchTimeout: System.TimeSpan) : Regex
active recognizer Parse: string -> 'a option
val area : obj
val prefix : obj
val suffix : 'a (requires member TryParse)
val printfn : format:Printf.TextWriterFormat<'T> -> 'T
Raw view Test code New version

More information

Link:http://fssnip.net/859
Posted:3 years ago
Author:Evgeniy Andreev
Tags: #active patterns , pattern matching , regex