In a recent post I talked about using String.forall for string matching over the use of Regex:

http://blogs.msdn.com/b/carlnol/archive/2011/10/20/f-string-extension-methods-rather-than-using-regex.aspx

I do however use Regex a lot for other types of processing. One thing I find myself doing a bit is capturing values from a Match. If you find yourself doing this a lot the Dynamic Lookup Operator allows one to define a simple model for extracting the captured group values:

let pattern = @"(?<AreaCode>^\d{3})[- ](?<PhoneNumber>\d{3}[- ]?\d{4}$)"

let catcher = RegexCatcher(pattern, "804-323-6205")
let areacode = catcher?AreaCode
let success = catcher.IsMatch

The outcome of this code is:

val catcher : RegexCatcher
val areacode : string = "804"
val success : bool = true

The RegexCatcher type is a simple type that enables one to initialize a Regex, with an associated search string, and then providing access the captured groups:

type RegexCatcher (regex:Regex, input:string) =
    
    let regexMatch = regex.Match(input)

    new(pattern:string, input:string, options:RegexOptions) =
        RegexCatcher(Regex(pattern, options), input)

    new(pattern:string, input:string) =
        RegexCatcher(Regex(pattern), input)

    member this.IsMatch
        with get() =
            regexMatch.Success

    member this.Match
        with get() =
            regexMatch

    static member (?) (regexCatcher:RegexCatcher, input:string) =
        regexCatcher.Match.Groups.[input].Value

Although the pattern is simple, I hope one will agree, that the code using this type is very succinct and easy to read.