Created
April 1, 2014 01:16
-
-
Save spiralx/9905898 to your computer and use it in GitHub Desktop.
Regular Expressions with Named Groups
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Allows you to specify named groups in regular expressions like in Perl/Python/.NET/etc. You have to | |
* use a string to specify the regex, and the function returns an object that has `exec` and `replace` | |
* functions like a normal RegExp object, but matches they generate have keys for the values of the named | |
* groups. | |
* | |
* n = NamedRegExp("(?<protocol>http|ftp)://(?<host>[\\w-]+\\.com)(?<path>/.+\\.html)?$"); | |
* res = n.exec("http://foobar.com"); -> res.protocol = http, res.host = foobar.com res.path = undefined | |
* res = n.exec("http://foobar.com/"); -> res.protocol = http, res.host = foobar.com res.path = / | |
* res = n.exec("http://foobar.com/index.html"); -> res.protocol = http, res.host = foobar.com res.path = /index.html | |
* | |
* n = NamedRegExp("(?<initial>[A-Z]) (?<surname>[A-Z][a-zA-Z]+)") | |
* n.replace("J Skinner, M Cow and F Baloney", function(m) { | |
* return m.surname + ", " + m.initial + "."; | |
* }) -> "Skinner, J., Cow M. and Baloney, F." | |
* | |
* @param {String} regex_str | |
* @param {String?} flags | |
* @return {NamedRegExp} | |
*/ | |
function NamedRegExp(regex_str, flags) { | |
var | |
name_order = [null], | |
plain_regex = regex_str.replace(/\(\?<(\w+)>/g, function(match, name) { | |
var i = name_order.indexOf(name); | |
if (i == -1) { | |
i = name_order.push(name); | |
} | |
return "("; | |
}), | |
matches_extend = function(matches) { | |
if (matches) { | |
for (var i = 1; i < matches.length; i++) { | |
matches[name_order[i]] = matches[i]; | |
} | |
} | |
return matches; | |
}; | |
return { | |
exec: function(src) { | |
var | |
re = RegExp(plain_regex, flags), | |
matches = re.exec(src); | |
return matches_extend(matches); | |
}, | |
replace: function(src, repl_func) { | |
var re = RegExp(plain_regex, "g" + flags); | |
return src.replace(re, function() { | |
var match = matches_extend(Array.from(arguments).slice(0, -2)); | |
//console.dir(arguments); | |
return repl_func(match); | |
}); | |
} | |
}; | |
} | |
// -------------------------------------------------------------------- | |
/** | |
* array_to_obj([1, 5, 6], "x y z") -> { x: 1, y: 5, z: 6 } | |
* array_to_obj([undefined, 4], ["score", "level"]) -> { level: 4 } | |
*/ | |
function arr_to_obj(arr, names) { | |
var keys = Array.isArray(names) ? names : names.split(" "), | |
obj = {}, | |
i = 0; | |
if (arr.length > keys.length) { | |
throw Error("Not enough key names!"); | |
} | |
for (; i < keys.length; i++) { | |
if (typeof arr[i] !== "undefined") { | |
obj[keys[i]] = arr[i]; | |
} | |
} | |
return obj; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment