Search This Blog

Loading...

Friday, February 13, 2009

"invalid range in character class": JavaScript Error Solved


"invalid range in character class"

It was maddening. Firebug showed this error, but gave no additional information: not even a script or function name, much less a line number. Googling didn't help very much: it suggested that it was an error involving regular expressions. Thousands and thousands of lines of code and at least half a dozen external JavaScript files later, I'm pleased to say that I discovered what the message means and now want to pass along the knowledge in hopes of saving someone else endless hours.

The short answer is that the word range refers to a "range of values," say the range from 1 to 100 typically written as 1-100. Notice that my shorthand for range involves a dash or minus sign between the 1 and 100. Therein lies the problem. If you want a regular expression to test for the presence of a dash/minus sign as a dash/minus sign, it needs to be escaped with a backslash, or else some browsers (Firefox 2 in this case) think that you are attempting to express a range instead and freak out accordingly.

In particular, I had one tiny function that was used on only one form dealing with phone numbers. Valid data included a blank space, any number, a dash, or a right or left parenthesis to accommodate a number such as (555) 555-5555. It wasn't crucial that users type in their phone number in any certain way, I just try to get in the practice of filtering my data both client and server side.

In a test copy of the production environment, I first eliminated my scripts one by one until the offending error disappeared. Then I brought that script back, eliminating each function body until the error disappeared. It turned out to be this tiny function, short for "is integer" though obviously adding the space, dash, and parentheses:
var isInt = function(s) {
    s.value = s.value.replace(/[^\d-()\s]+/g, '');
};
Notice that the - character is not escaped. Now here's the fix:
var isInt = function(s) {
    s.value = s.value.replace(/[^\d\-()\s]+/g, '');
};
I have now added the escape \-, and thousands of lines of code are now working again. Hopefully this post will save someone else hours of frustration.

Update: As Earl suggests in his comment below, you can also move the dash to the end of your regular expression square brackets without using an escape: /[^\d()\s-]+/g. 5n1p3r also brings up the point below that if you're using the RegExp object and an escape, you need two backslashes, the first to escape your escape.

33 comments:

  1. Thank you, thank you, THANK YOU! That error was driving me NUTS. As far as I'm concerned, your place in heaven is assured.

    ReplyDelete
  2. Glad I could be of help. :)

    ReplyDelete
  3. Same here. Was doing CompSci homework for David Reed's "A Balanced Introduction to Computer Science" 2nd ed. and Exercise 15.11 did not say anything about needing a backslash prior to "-". But that was exactly was making the page not work.

    Genius!

    ReplyDelete
  4. yes, it was my problem too. I solved it, puting the '-' in the final list, eg: [0-9 -]

    ReplyDelete
  5. Great!!! It will help even when using GWT!!!!

    ReplyDelete
  6. Thanks, helped me to figure out an issue I was having... just wanted to add that if you are using the RegExp object (like I was...) you have to escape your backslashses as well so it would look like: \\- rather than just \-

    ReplyDelete
  7. THANK YOU!!! I was becoming mad! ^^'

    ReplyDelete
  8. thanks man you have saved my hours of debugging for this error

    ReplyDelete
  9. I had that exact needle in the haystack and your tip just made the hay vanish. My JS reg exp with a "-" now has a preceding "\" to escape it. Simple when you know how. Thank you.

    ReplyDelete
  10. Thanks a lot! After hours of frustration I could finally fixed my js thanks to your advice.

    ReplyDelete
  11. A million blessings be upon you in the name of JehovahScript.

    ReplyDelete
  12. Thanks a million. You just saved me hours.

    ReplyDelete
  13. I will repeat what everyone says and add one more...you are truly a wonderful, compassionate human being.

    ReplyDelete
  14. Thank you so much! I had the same problem and this helped immensely to hunt it down.

    ReplyDelete
  15. Hey, the other way to resolve this is to make sure the '-' is either the first or last character in the character set (i.e. inside the []). So, instead of '[^\d-() ]', you can do '[^\d() -]'.

    Also, for an exceptional article on phone number regular expressions, check out the master's post:

    http://blog.stevenlevithan.com/archives/validate-phone-number

    ReplyDelete
  16. thanks a lot....

    ReplyDelete
  17. From encountering the problem to solved took about three minutes thanks to your post. Thank you!

    ReplyDelete
  18. THANK YOU! You saved me a ton of time.

    ReplyDelete
  19. Thank you, I had the same problem. Thanks to you, i don't have to waste hours of my time searching for the origin.

    ReplyDelete
  20. ОГРОМНОЕ СПАСИБО!!!

    ReplyDelete
  21. hmm.. who knew.. thnx

    ReplyDelete
  22. Hello,
    Here is a reason of you error:
    http://forums.smartclient.com/showthread.php?t=524
    Doubling all the backslashes will solve the issue.

    ReplyDelete
  23. You are a god sir. I will no go sacrifice some burritos by eating them in your honor. Thanks for this SOOOOOOO much!

    ReplyDelete
  24. You're quite welcome. Same to everybody else who's posted happy comments. ;)

    ReplyDelete
  25. You are terrific. Really you saved my soul and hours.

    ReplyDelete
  26. Thx! You saved me a couple hours of debuging!

    ReplyDelete
  27. Thanks a lot! I had this issue and I didn't know what was going on. I thought it was with my actionscript but it was my regex in javascript.

    ReplyDelete
  28. This was awesome, thank you!

    ReplyDelete