4 people like it.

Type based Regex Active Patterns

Regex match via Active Patterns with Type based value extraction.

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
// Based on http://blogs.msdn.com/b/chrsmith/archive/2008/02/22/regular-expressions-via-active-patterns.aspx

open System
open System.Text.RegularExpressions
  

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

let convert<'ToType> value = Convert.ChangeType(value, typeof<'ToType>) :?> 'ToType
let (|Match3|_|) (pat:string) (inp:string) : ('T1 * 'T2 * 'T3) option =
    match (|Match|_|) pat inp with
    | Some (fst :: snd :: trd :: []) -> 
        try 
            Some (convert<'T1> fst, convert<'T2> snd, convert<'T3> trd) 
        with _ -> failwith "Match3 succeeded, but with type conversion errors"
    | Some [] -> failwith "Match3 succeeded, but no groups found. Use '(.*)' to capture groups"
    | Some _ -> failwith "Match3 succeeded, but did not find exactly three matches."
    | None -> None  

// Example
let (month, day, year) : (int * int * int) =
    match DateTime.Now.ToString() with
    | Match3 "(\d*)/(\d*)/(\d*).*" (a,b,c) -> (a,b,c)
    | _ -> failwith "Match Not Found."
namespace System
namespace System.Text
namespace System.Text.RegularExpressions
type Match =
  inherit Group
  member Groups : GroupCollection
  member NextMatch : unit -> Match
  member Result : replacement:string -> string
  static member Empty : Match
  static member Synchronized : inner:Match -> Match

Full name: System.Text.RegularExpressions.Match
val pat : string
Multiple items
val string : value:'T -> string

Full name: Microsoft.FSharp.Core.Operators.string

--------------------
type string = String

Full name: Microsoft.FSharp.Core.string
val inp : string
val m : Match
Multiple items
type Regex =
  new : pattern:string -> Regex + 1 overload
  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 Matches : input:string -> MatchCollection + 1 overload
  member Options : RegexOptions
  member Replace : input:string * replacement:string -> string + 5 overloads
  ...

Full name: System.Text.RegularExpressions.Regex

--------------------
Regex(pattern: string) : unit
Regex(pattern: string, options: RegexOptions) : unit
Regex.Match(input: string, pattern: string) : Match
Regex.Match(input: string, pattern: string, options: RegexOptions) : Match
property Group.Success: bool
union case Option.Some: Value: 'T -> Option<'T>
Multiple items
module List

from Microsoft.FSharp.Collections

--------------------
type List<'T> =
  | ( [] )
  | ( :: ) of Head: 'T * Tail: 'T list
  interface IEnumerable
  interface IEnumerable<'T>
  member Head : 'T
  member IsEmpty : bool
  member Item : index:int -> 'T with get
  member Length : int
  member Tail : 'T list
  static member Cons : head:'T * tail:'T list -> 'T list
  static member Empty : 'T list

Full name: Microsoft.FSharp.Collections.List<_>
val tail : list:'T list -> 'T list

Full name: Microsoft.FSharp.Collections.List.tail
val g : Group
property Match.Groups: GroupCollection
property Capture.Value: string
union case Option.None: Option<'T>
val convert : value:string -> 'ToType

Full name: Script.convert
val value : string
type Convert =
  static val DBNull : obj
  static member ChangeType : value:obj * typeCode:TypeCode -> obj + 3 overloads
  static member FromBase64CharArray : inArray:char[] * offset:int * length:int -> byte[]
  static member FromBase64String : s:string -> byte[]
  static member GetTypeCode : value:obj -> TypeCode
  static member IsDBNull : value:obj -> bool
  static member ToBase64CharArray : inArray:byte[] * offsetIn:int * length:int * outArray:char[] * offsetOut:int -> int + 1 overload
  static member ToBase64String : inArray:byte[] -> string + 3 overloads
  static member ToBoolean : value:obj -> bool + 17 overloads
  static member ToByte : value:obj -> byte + 18 overloads
  ...

Full name: System.Convert
Convert.ChangeType(value: obj, conversionType: Type) : obj
Convert.ChangeType(value: obj, typeCode: TypeCode) : obj
Convert.ChangeType(value: obj, conversionType: Type, provider: IFormatProvider) : obj
Convert.ChangeType(value: obj, typeCode: TypeCode, provider: IFormatProvider) : obj
val typeof<'T> : Type

Full name: Microsoft.FSharp.Core.Operators.typeof
type 'T option = Option<'T>

Full name: Microsoft.FSharp.Core.option<_>
Multiple items
active recognizer Match: string -> string -> string list option

Full name: Script.( |Match|_| )

--------------------
type Match =
  inherit Group
  member Groups : GroupCollection
  member NextMatch : unit -> Match
  member Result : replacement:string -> string
  static member Empty : Match
  static member Synchronized : inner:Match -> Match

Full name: System.Text.RegularExpressions.Match
val fst : string
val snd : string
val trd : string
val failwith : message:string -> 'T

Full name: Microsoft.FSharp.Core.Operators.failwith
val month : int

Full name: Script.month
val day : int

Full name: Script.day
val year : int

Full name: Script.year
Multiple items
val int : value:'T -> int (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.int

--------------------
type int = int32

Full name: Microsoft.FSharp.Core.int

--------------------
type int<'Measure> = int

Full name: Microsoft.FSharp.Core.int<_>
Multiple items
type DateTime =
  struct
    new : ticks:int64 -> DateTime + 10 overloads
    member Add : value:TimeSpan -> DateTime
    member AddDays : value:float -> DateTime
    member AddHours : value:float -> DateTime
    member AddMilliseconds : value:float -> DateTime
    member AddMinutes : value:float -> DateTime
    member AddMonths : months:int -> DateTime
    member AddSeconds : value:float -> DateTime
    member AddTicks : value:int64 -> DateTime
    member AddYears : value:int -> DateTime
    ...
  end

Full name: System.DateTime

--------------------
DateTime()
   (+0 other overloads)
DateTime(ticks: int64) : unit
   (+0 other overloads)
DateTime(ticks: int64, kind: DateTimeKind) : unit
   (+0 other overloads)
DateTime(year: int, month: int, day: int) : unit
   (+0 other overloads)
DateTime(year: int, month: int, day: int, calendar: Globalization.Calendar) : unit
   (+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int) : unit
   (+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, kind: DateTimeKind) : unit
   (+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, calendar: Globalization.Calendar) : unit
   (+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, millisecond: int) : unit
   (+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, millisecond: int, kind: DateTimeKind) : unit
   (+0 other overloads)
property DateTime.Now: DateTime
DateTime.ToString() : string
DateTime.ToString(provider: IFormatProvider) : string
DateTime.ToString(format: string) : string
DateTime.ToString(format: string, provider: IFormatProvider) : string
active recognizer Match3: string -> string -> ('T1 * 'T2 * 'T3) option

Full name: Script.( |Match3|_| )
val a : int
val b : int
val c : int

More information

Link:http://fssnip.net/4J
Posted:6 years ago
Author:Nick Palladinos
Tags: regex , active patterns