Pages

Regular expressions with JavaScript

We could build by hand complex validation functions for our JavaScript code, but it is not a good idea. We should use instead the regular expession tool that is part of the JavaScript engine, that is close enough to other popular regex engines, like the Perl one.

In JavaScript, a regular expression is an object of a specific class (RegExp) that is created in a specific way. For instance, here is a regular expression that defines a ZIP code respecting the rule "a string of exactely 5 digit":
var pattern = /^\d{5}$/
A regular expression is delimited by two slashes. So, if we want to put a slash in a regular expression we need to escape it with a backslash.

The first character in our first regex is a "^" that stands as a marker for the beginning of the string, then we have a "\d", meaning a digit, than a specifier "{5}" that tells us that the regex is expecting 5 items just specified, i.e. five digits, and finally a "$", marker for the end of the string.

Reading all together this means: we are expecting a string described from the beginning to the end by exactely 5 digits.

To start using regular expression in JavaScript you should have a grasp on a few metacharacters:
  • . = any character but a newline
  • \d = any digit
  • \w = any alphanumeric character
  • \s = any whitespace (blank, tab, return, newline)
  • ^ = marker to the beginning of text
  • $ = marker to the end of text
  • * = preceding subpattern appears 0+ times
  • + = preceding subpattern appears 1+ times
  • ? = preceding subpattern appears 0 or 1 time
  • {n} = preceding subpattern appears exactely n times
  • () = delimiter for a subpattern

Once we create a regex, it is easy to check if a string comply to its request, we just call the method test() on the regex passing the string to be tested as parameter. Here is a function we can use to validate our text inputs:

function patternCheck(fldInput, regex, fldHelp) {

if(!regex.test(fldInput.value)) {
if(fldHelp != null) {
fldHelp.innerHTML = "Should match the pattern: " + regex.source;
return;
}
}
else {
if(fldHelp != null)
fldHelp.innerHTML = "";
}
}

In the source property of the regex we have access to the regular expression as a string, we display it to the user as an hint for the reason why we didn't accept his input - hoping this is not gibberish to him.

This is the HTML block that would display a text input for a ZIP:

<p>ZIP code:
<input id="zipId" name="zip" type="text" size="5"
onblur="patternCheck(this, /^\d{5}$/, document.getElementById('zipHlp'))" />
<i><span id="zipHlp"></span></i></p>

If we want to specify a valid range for the number of elements that should be in a regular expression, we can use the construct {min,max}, meaning that there should be at least "min" elements, and at the most "max" of them.

So we can rewrite the text input we should accept 3-12 character string in this way:

<p>Your input:
<input id="msgId" name="message" type="text" size="10"
onblur="patternCheck(this, /^\w{3,12}$/, document.getElementById('msgHlp'))" />
<i><span id="msgHlp"></span></i></p>

We can offer a limited option to the user, using the "|" operator. Here is how we permit to input just "blue" or "red":

<p>Color:
<input id="colorId" name="color" type="text" size="10"
onblur="patternCheck(this, /^(blue|red)$/, document.getElementById('colorHlp'))" />
<i><span id="colorHlp"></span></i></p>


More details on regular expression in chapter seven of Head First JavaScript.

No comments:

Post a Comment