Prologue
Every time I need to use JavaScript there’s this tiny voice in the back of my head “Please don’t”, for instance because of
JavaScript has two sets of equality operators: ===
and !==
, and their evil twins ==
and !=
.
Verify a URI in JavaScript with a Regular Expression using Google Search examples
This time it did it again: I used JavaScript. My need was to verify a basic URI in JavaScript, so I wrote this function based on RFC 3986 [WayBack] which in Appendix B has a nice regular expression: ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?
function isValidUri(uri){
var uriRegExPattern = "^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?";
var uriRegEx = new RegExp(uriRegExPattern);
return (uriRegEx.test(uri));
}
It would crash. But JavaScript is JavaScript, so even a site like JSFiddle wouldn’t show an error (later I found out that enabling the console on http://jsbin.com/wamavacuco/edit?html,console,output does show the error in the console complete with stack trace).
So I would write an exception handler around them like dozens of exception handling examples performing an alert using a description property or message property.
try {
// function body
}
catch (e) {
alert("isValidUri Error: " + e.description);
return false;
}
Finally I got the exceptions right and wrote this exception handler around it:
try {
// function body
}
catch (e) {
alert("isValidUri Error: " + e);
return false;
}
Now I finally got a decent error message:
isValidUri error: SyntaxError: Invalid regular expression: /^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(?([^#]*))?(#(.*))?/: Invalid group
Conclusion
I learned two lessons here:
- When you write in a new programming language, don’t trust the Google Search results. The worst recommendations get the best hits, in this case for the exception handling in JavaScript.
- Do not trust all regular expressions to be supported in any environment. There are too many regex flavours. No environment supports them all.
Epilogue
This was the jsbin stack trace:
"error"
"SyntaxError: Invalid regular expression: /^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(?([^#]*))?(#(.*))?/: Invalid group
at RegExp (native)
at isValidUri (:6:26)
at HTMLButtonElement.onclick (http://null.jsbin.com/runner:1:968)"
The RegEx101 Python interpreter understands the regex and supports seamless switch to JavaScript support or PCRE support. I hoped this would enabled me to fiddle around long enough. But it didn’t show the error. Apparently it doesn’t fully do what JavaScript does.
The cause was (after a long search) answered in Invalid Group with Regex Expression in Javascript – Stack Overflow – thanks melpomene: either escape backslashes or use slash surrounded regex literals.
/1?[\s-]?\(?(\d{3})\)?[\s-]?(\d{3})[\s-]?(\d{4})/
works fine in JavaScript.
However, my crystal ball says you’re using a string that you’re passing to the RegExp
constructor:
new RegExp("1?[\s-]?\(?(\d{3})\)?[\s-]?(\d{3})[\s-]?(\d{4})")
This is wrong because backslashes have a special meaning in strings, so
"1?[\s-]?\(?(\d{3})\)?[\s-]?(\d{3})[\s-]?(\d{4})"
is equivalent to
"1?[s-]?(?(d{3}))?[s-]?(d{3})[s-]?(d{4})"
(because "\("
is "("
). That would complain about an invalid group at (?(
.
Solution: Either use a regex literal (/.../
) or double your backslashes in the string.
–jeroen
Like this:
Like Loading...
Related
Leave a Reply