Skip to content

Instantly share code, notes, and snippets.

@sadache
Created April 4, 2010 18:48
Show Gist options
  • Save sadache/355611 to your computer and use it in GitHub Desktop.
Save sadache/355611 to your computer and use it in GitHub Desktop.
module UrlPatterns
open System.Text.RegularExpressions
let t2 a b=(a,b)
let matchUrl pattern:string->(Map<string,string>* string ) Option=
let regex=(new Regex(pattern))
let names= regex. GetGroupNames()
in fun url -> let m=regex.Match(url)
if not(m.Success) then None
else let groups= m.Groups in
let paramMap=[for i in 0..groups.Count do
let key= regex.GroupNameFromNumber(i)
if not <| System.String.IsNullOrEmpty key
then yield (regex.GroupNameFromNumber(i), groups.[i].Value)] |> Map.ofList
in Some(paramMap,defaultArg <| paramMap.TryFind "rest" <| "")
let urlParams= matchUrl "Show/(?<topics>.*)/(?<id>[\\d]+)/(?<title>[-\\w]+)/(?<rest>.*)" "http://localhost/Show/Topic/SubTopic/SubSubTopic/123/This-is-an-example/rest/evenmore/tomatch/later"
//evaluates to
val t2 : 'a -> 'b -> 'a * 'b
val matchUrl : string -> (string -> Option<Map<string,string> * string>)
val urlParams : Option<Map<string,string> * string> =
Some
(map
[("0",
"Show/Topic/SubTopic/SubSubTopic/123/This-is-an-example/rest/e"+[21 chars]);
("id", "123"); ("rest", "rest/evenmore/tomatch/later");
("title", "This-is-an-example");
("topics", "Topic/SubTopic/SubSubTopic")],
"rest/evenmore/tomatch/later")
@sadache
Copy link
Author

sadache commented Apr 5, 2010

now the passed pattern can provide a named group that is left to be matched but the next matcher (somehow similar to head:tail analogy). Allowing even more flexible url matching. Of course now I have to work on the simplified syntax for simple casual needs using {}.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment