Thursday, February 11, 2010

JavaScript: Variables in regular expressions

Often, you want to look for a particular pattern within a string. Let's say you know that you want to look for the string "revenue" inside a given string.

function match_string_for_revenue(string_for_searching)
{
return string_for_searching.match(/revenue/gi);
}
var our_string = "We are looking for ReVeNuE.";
alert( match_string_for_revenue(our_string) );

You can store the pattern as a regular expression in its own JavaScript variable, which makes your code more readable and its intention better known.
function match_string_for_revenue(string_for_searching)
{
var pattern_to_look_for = /revenue/gi;
return string_for_searching.match(pattern_to_look_for);
}
var our_string = "We are looking for ReVeNuE.";
alert( match_string_for_revenue(our_string) );

But what if you want to generalize this matching and be able to search for any given pattern? Can you make it vary based on a parameter given, instead of keeping it in the code?
/* NOT GOING TO WORK */
function match_string(string_for_searching, valuable_substring)
{
var pattern_to_look_for = / + valuable_substring + /gi;
return string_for_searching.match(pattern_to_look_for);
}
var our_string = "We are looking for ReVeNuE.";
alert( match_string(our_string, "revenue") );

Well, that didn't work. What happened? That last alert() should have given you a null, which means that it wasn't able to match the pattern as expected.

Are we stuck? No. We just have to work around this using eval().
function match_string(string_for_searching, substring)
{
eval("var pattern_to_look_for = /" + substring + "/gi");
string_for_searching.match(pattern_to_look_for);
}
var our_string = "We are looking for ReVeNuE.";
alert( match_string(our_string, "revenue") );

This method will also work with Ruby and any other language that gives you the option to evaluate the contents of a string as code in that language.

Sometimes you'll find yourself having to generate code dynamically from a given string because there's no other way but to write real code in that language in a way that goes beyond merely passing in a string. If the language doesn't support having a string in there during the course of its normal operation, that's where eval() can come in handy.

Important Update (July 14, 2010): It's important, as Matt Austin points out, to consider the security implications of using eval(). See his comment below. Additionally, coderrr rightly pointed out that there's a more proper way to do it using RegExp:
function match_string(string_for_searching, substring)
{
return string_for_searching.match(new RegExp(substring, "gi"));
}

var our_string = "We are looking for ReVeNuE.";
alert(match_string(our_string, "revenue"));

This is the way I'd recommend doing it in the future. The specific use of eval() that triggered my idea for this post was free from the security concerns Matt raised, but seeing as how this post describes general usage, please use eval() sparingly or consider security implications of the kind Matt described.

blog comments powered by Disqus