Skip to content

Instantly share code, notes, and snippets.

@chrisforbes
Created November 29, 2009 23:46
Show Gist options
  • Save chrisforbes/245134 to your computer and use it in GitHub Desktop.
Save chrisforbes/245134 to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace MultiRegex
{
class Program
{
static void Main(string[] args)
{
var mr = new MultiRegex(new Dictionary<string, string>()
{
{ @"(\d+)", "number" },
{ @"\b([a-zA-Z_][a-zA-Z0-9_]+)\b", "ident" },
{ @";", "punct" },
});
var input = "76 trombones led the big parade;" +
"With a 110 cornets close at hand ...";
var toks = ParseWithMulti(mr, input);
foreach( var t in toks )
Console.WriteLine(t);
}
static IEnumerable<string> ParseWithMulti(MultiRegex mr, string input)
{
var index = 0;
while( index < input.Length )
{
var m = mr.Match(input, index);
if (m == null) yield break;
yield return m.tag;
index = m.m.Index + m.m.Length;
}
}
}
class MultiRegex
{
readonly Regex r;
public MultiRegex(Dictionary<string, string> vs)
{
r = new Regex(vs
.Select(v => "(?<{0}>{1})".F(v.Value, v.Key))
.JoinWith("|"));
}
public MultiMatch Match(string s) { return Match(s, 0); }
public MultiMatch Match(string s, int start)
{
var m = r.Match(s, start);
if (!m.Success) return null;
var namedGroups = r.GetGroupNames().Where(g => !char.IsDigit(g[0]));
var tag = namedGroups
.Select(x => new { t = x, g = m.Groups[x] })
.Where(g => g.g.Success)
.OrderBy(g => g.g.Index)
.FirstOrDefault();
if (tag == null) return null;
return new MultiMatch(m, tag.t);
}
}
class MultiMatch
{
public readonly Match m;
public readonly string tag;
public MultiMatch(Match m, string tag)
{
this.m = m;
this.tag = tag;
}
}
static class Exts
{
public static string F( this string f, params object[] args )
{
return string.Format( f, args );
}
public static string JoinWith<T>(this IEnumerable<T> ts, string sep)
{
return string.Join(sep, ts.Select(t => t.ToString()).ToArray());
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment