This may not work for your situation, but I would like to provide it here for future searchers.
$.fn.regexFilter = function (expression, flags) {
flags = flags != null ? flags : "g";
if (expression.constructor === String) {
// simple string expression
expression = new RegExp(expression, flags);
} else if (expression.constructor === Array) {
// turns ["a", "b", "c"] into (a)|(b|(c)
expression = new RegExp("(" + expression.join(')|(') + ")", flags);
}
// objects in the form of {expression: "foo", flags: "gim" }
else if (typeof expression === "object" && expression.foo) {
expression = new RegExp(expression.expression, expression.flags != null ? expression.flags : flags);
} else if (expression.constructor !== RegExp) {
// otherwise we assume no mathes
return $();
}
// list of matches
var matches = [];
// list of matching elements
var $matches = this.filter(function () {
var haystack = $(this).text();
var match = haystack.match(expression);
matches.push(match);
$(this).data('match', match);
return !!match;
});
$matches.matches = matches;
return $matches;
};
These are all equivalent, and match any <p>
with a word starting with "c":
$('p').regexFilter('\\bc\\w+', 'g').css({
color: 'green'
});
$('p').regexFilter(/\bc\w/g).css({
color: 'green'
});
$('p').regexFilter({expression: '\\bc\\w+', flags: 'g'}).css({
color: 'green'
});
You can also retrieve the submatches in any function. Here we match the first two words. The second word is stored in group 1.
$('p').regexFilter(/^\w+\s(\w+)/).each(function () {
var match = $(this).data('match');
var oldText = ["the second word of <i>", $(this).text(), "</i> is", match[1]].join(" ");
$(this).html(oldText);
});
You can also just get the array of matches for all elements.
var $matchedElements = $('p').regexFilter(/^\w+\s(\w+)/);
var matches = $matchedElements.matches;
matches[3][1] // the second word of the 4th p
Note that this match array doesn't persist, and there will be nulls
in the array. So the 4th p is $(p)[3]
, not $matchedElements[3]
.