anchor.diff:              finalPairing |> Array.iter(fun (r, p) -> writeCard(r, p)))
           ()
   
  -    member private this.RunGameExport(game: string, lesson: string option) = 
  +    member private this.RunGameExport(game: string, lesson: string option, lessonRegex: string option) = 
  +        let filterGame(gid: int)(l: LessonRecord) = 
  +            (l.GameID = gid)
  +        let filterLessonsNoWildcard(gid: int, name: string)(l: LessonRecord) = 
  +            filterGame(gid)(l) && (l.Name = name)
  +        let filterLessonsWildcard(gid: int, name: string)(l: LessonRecord) = 
  +            let rootName = name.Substring(0, name.IndexOf('*'))
  +            filterGame(gid)(l) && (l.Name.StartsWith(rootName, StringComparison.CurrentCultureIgnoreCase))
  +        let filterLessonsRegex(gid: int, regex: Regex)(l: LessonRecord) = 
  +            filterGame(gid)(l) && (regex.IsMatch(l.Name))
  +
           match (LLDatabase.Games |> Array.tryFind(fun t -> t.Name = game)) with
           | Some(g) -> 
  -            let lessonsToExport = 
  -                match lesson with
  -                | Some(l) when not(l.Contains("*")) -> 
  -                    LLDatabase.Lessons |> Array.tryFind(fun t -> (t.GameID = g.ID) && (t.Name = l)) |> Option.toArray
  -                | Some(l) when l.Contains("*") ->
  -                    // wildcard
  -                    let rootName = l.Substring(0, l.IndexOf('*'))
  -                    LLDatabase.Lessons |> Array.filter(fun t -> (t.GameID = g.ID) && t.Name.StartsWith(rootName))
  -                | _ -> LLDatabase.Lessons |> Array.filter(fun t -> t.GameID = g.ID)
  +            // prefer the regex over using the name
  +            let lessonFilter = 
  +                match (lesson, lessonRegex) with
  +                | (_, Some(regex)) -> filterLessonsRegex(g.ID, new Regex(regex))
  +                | (Some(l), _) when not(l.Contains("*")) -> filterLessonsNoWildcard(g.ID, l)
  +                | (Some(l), _) -> filterLessonsWildcard(g.ID, l)
  +                | _ -> filterGame(g.ID)
  +
  +            let lessonsToExport = LLDatabase.Lessons |> Array.filter lessonFilter
  +            let reportLessonExport(l: LessonRecord) =
  +                outputTextWriter.WriteLine("Exporting lesson [" + l.Name + "]")
  +                l
   
               use outStream = new StreamWriter(config.ExportPath)
  -            lessonsToExport |> Array.iter(this.RunLessonExport(g, outStream))
  +            lessonsToExport |> Array.iter(reportLessonExport >> this.RunLessonExport(g, outStream))
           | _ -> 
               outputTextWriter.WriteLine("Couldn't find entry for game '" + game + "'")
           ()
  
positive.code:             match config.LessonToExport with
              | "" -> None
              | l -> Some(l)
          this.RunGameExport(config.GameToExport, lessonParam)
          ()
negative.code: 
  open LLDatabase
  open LudumLinguarumPlugins
  open System
  open System.IO
  open System.Text.RegularExpressions
  
  type AnkiExporterConfiguration() = 
      [<CommandLine.Option("game", Required = true)>]
      member val GameToExport = "" with get, set
  
      [<CommandLine.Option("lesson", Required = false)>]
      member val LessonToExport = "" with get, set
  
      [<CommandLine.Option("lesson-regex", Required = false)>]
      member val LessonRegexToExport = "" with get, set
  
      [<CommandLine.Option("export-path", Required = true)>]
      member val ExportPath = "" with get, set
  