Non-strict parsing, manipulation, and fuzzy matching of URLs in Elixir.
The full documentation for Fuzzyurl is here.
To use Fuzzyurl with your projects, edit your mix.exs
file and
add it as a dependency:
defp deps do
[{:fuzzyurl, "~> 0.9.0"}]
end
Fuzzyurl provides two related functions: non-strict parsing of URLs or URL-like strings into their component pieces (protocol, username, password, hostname, port, path, query, and fragment), and fuzzy matching of URLs and URL patterns.
Specifically, URLs that look like this:
[protocol ://] [username [: password] @] [hostname] [: port] [/ path] [? query] [# fragment]
Fuzzyurls can be constructed using some or all of the above
fields, optionally replacing some or all of those fields with a *
wildcard if you wish to use the Fuzzyurl as a URL mask.
iex> f = Fuzzyurl.from_string("https://api.example.com/users/123?full=true")
%Fuzzyurl{fragment: nil, hostname: "api.example.com", password: nil, path: "/users/123", port: nil, protocol: "https", query: "full=true", username: nil}
iex> f.protocol
"https"
iex> f.hostname
"api.example.com"
iex> f.query
"full=true"
iex> f = Fuzzyurl.new(hostname: "example.com", protocol: "http", port: "8080")
%Fuzzyurl{fragment: nil, hostname: "example.com", password: nil, path: nil, port: "8080", protocol: "http", query: nil, username: nil}
iex> Fuzzyurl.to_string(f)
"http://example.com:8080"
Fuzzyurl supports wildcard matching:
*
matches anything, includingnil
.foo*
matchesfoo
,foobar
,foo/bar
, etc.*bar
matchesbar
,foobar
,foo/bar
, etc.
Path and hostname matching allows the use of a greedier wildcard **
in
addition to the naive wildcard *
:
*.example.com
matchesfilsrv-01.corp.example.com
but notexample.com
.**.example.com
matchesfilsrv-01.corp.example.com
andexample.com
./some/path/*
matches/some/path/foo/bar
and/some/path/
but not/some/path
/some/path/**
matches/some/path/foo/bar
and/some/path/
and/some/path
The Fuzzyurl.mask/0
and Fuzzyurl.mask/1
functions aid in the
creation of URL masks.
iex> m = Fuzzyurl.mask
%Fuzzyurl{fragment: "*", hostname: "*", password: "*", path: "*", port: "*", protocol: "*", query: "*", username: "*"}
iex> Fuzzyurl.matches?(m, "http://example.com/a/b/c")
true
iex> m2 = Fuzzyurl.mask(path: "/a/b/**")
%Fuzzyurl{fragment: "*", hostname: "*", password: "*", path: "/a/b/**", port: "*", protocol: "*", query: "*", username: "*"}
iex> Fuzzyurl.matches?(m2, "https://example.com/a/b/")
true
iex> Fuzzyurl.matches?(m2, "git+ssh://[email protected]/a/b")
true
iex> Fuzzyurl.matches?(m2, "https://example.com/a/bar")
false
Fuzzyurl.best_match
, given a list of URL masks and a URL, will return
the mask which most closely matches the URL:
iex> masks = ["/foo/*", "/foo/bar", Fuzzyurl.mask]
iex> Fuzzyurl.best_match(masks, "http://example.com/foo/bar")
"/foo/bar"
If you'd prefer the list index of the best-matching URL mask, use
Fuzzyurl.best_match_index
instead:
iex> masks = ["/foo/*", "/foo/bar", Fuzzyurl.mask]
iex> Fuzzyurl.best_match_index(masks, "http://example.com/foo/bar")
1
Fuzzyurl is copyright 2014-2016, Pete Gamache.
Fuzzyurl is released under the MIT License, available at LICENSE.txt.