JavaScript正则表达式遇到的小坑

其实也不是什么坑
在写短网址生成器的时候需要进行url的有效性验证,于是需要用到正则表达式。

1
2
3
4
5
var originUrl = input.value; 
var reg = new RegExp('^https?://(([a-zA-Z\d]+\.)?[a-zA-z\d]+\.(com|net|org|cn|com\.cn|hk|cc|me|xyz)|(\d{1,3}\.){3}\d{1,3})(:\d+)?/\S*');
if(!reg.test(originUrl)){
// ...
}

正则应该没有写错的,可结果却愣是匹配失败。于是翻阅《JavaScript高级程序设计》,终于找到了结果。

由于RegExp构造函数的模式参数是字符串,所以在某些情况下要对字符进行双重转义。所有元字符都必须双重转义…

所以将上面的代码改成这样就行了

1
var reg = new RegExp('^https?://(([a-zA-Z\\d]+\\.)?[a-zA-Z\\d]+\\.(com|net|org|cn|com\\.cn|hk|cc|me|xyz)|(\\d{1,3}\\.){3}\\d{1,3})(:\\d+)?/\\S*');

或者直接用字面量

1
/^https?://(([a-zA-Z\d]+\.)?[a-zA-z\d]+\.(com|net|org|cn|com\.cn|hk|cc|me|xyz)|(\d{1,3}\.){3}\d{1,3})(:\d+)?/\S*/.test(originUrl);

再多写几行,我不喜欢正则的字面量,因为在ES3中,正则字面量始终会共享同一个RegExp实例。而在ES5中,正则字面量就会像直接调用RegExp构造函数一样,每次都生成一个新的RegExp实例。为了兼容性,还是直接用RegExp好。