Alexander Manekovskyi

Writing About Tech

Adding Client-Side Validation Support for PhoneAttribute or Fighting the Lookbehind in JavaScript

Today, I was working on JavaScript implementation of validation routine for PhoneAttribute in context of my hobby project DAValidation. Examining the sources of .NET 4.5 showed that the validation is done via regular expression:

Unsupported lookbehind part of phone validation regexp pattern

And here is the problem - the pattern uses lookbehind feature that is not supported in JavaScript. Quote from regular-expressions.info:

Finally, flavors like JavaScript, Ruby and Tcl do not support lookbehind at all, even though they do support lookahead.

This lookbehind is used to match the “+” sign at the beginning of string, i. e. check the existence of the prefix. To make this work in JavaScript pattern should be reversed and lookbehind assertion should be replaced with lookahead (replace prefix check to suffix). And that’s it! The resulting pattern is:

1
^(\d+\s?(x|\.txe?)\s?)?((\)(\d+[\s\-\.]?)?\d+\(|\d+)[\s\-\.]?)*(\)([\s\-\.]?\d+)?\d+\+?\((?!\+.*)|\d+)(\s?\+)?$

As a proof here is test html page:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<html>
    <head>
        <title>Phone Number RegExp Test Page</title>
    </head>
    <body>
        <script>
            function validateInput() {
                var phoneRegex = new RegExp("^(\\d+\\s?(x|\\.txe?)\\s?)?((\\)(\\d+[\\s\\-\\.]?)?\\d+\\(|\\d+)[\\s\\-\\.]?)*(\\)([\\s\\-\\.]?\\d+)?\\d+\\+?\\((?!\\+.*)|\\d+)(\\s?\\+)?$", "i");

                var input = document.getElementById("tbPhone");
                var value = input.value.split("").reverse().join("");
                alert(phoneRegex.test(value));
            }
        </script>

        <input type="text" id="tbPhone" />
        <button onclick="javascript:testPhone()">Validate</button>
    </body>
</html>

While working on pattern reversing I was using my favorite regular expressions building and testing tool Expresso. Also, a great article of Steven Levithan Mimicking Lookbehind in JavaScript helped to look deeper and actually find the right solution of the problem.

PS. Now, as I finally finished adding support for new .NET 4.5 validation attributes the new version of DAValidation will be published soon. Stay tuned ;)

Comments