您的位置:首页 > Web前端 > JavaScript

常用正则表达式

2013-02-04 16:31 162 查看
引自:http://nuysoft.iteye.com/blog/1217898

Js代码  


作者:nuysoft/JS攻城师/高云 QQ:47214707 EMail:nuysoft@gmail.com      

声明:本文为原创文章,如需转载,请注明来源并保留原文链接。  

后文预告:jQuery中的正则表达式分析  

Js代码  


2.4 常用正则表达式  

在网上找到一篇广为流传的文章《常用正则表达式》,逐一分析,不足地方进行补充和纠正。  

Js代码  


常用的数字正则(严格匹配)  

  

正则  含义  

^[1-9]\d*$  匹配正整数  

^-[1-9]\d*$ 匹配负整数  

^-?[1-9]\d*$    匹配整数  

^[1-9]\d*|0$    匹配非负整数(正整数 + 0)  

^-[1-9]\d*|0$   匹配非正整数(负整数 + 0)  

^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$  匹配正浮点数  

^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$   匹配负浮点数  

^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$     匹配浮点数  

^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$ 匹配非负浮点数(正浮点数 + 0)  

^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$    匹配非正浮点数(负浮点数 + 0)  

Js代码  


常用字符串正则  

  

正则  含义  补充  

^[A-Za-z]+$ 匹配由26个英文字母组成的字符串    或 /^[a-z]+$/i  

^[A-Z]+$    匹配由26个英文字母的大写组成的字符串   

^[a-z]+$    匹配由26个英文字母的小写组成的字符串   

^[A-Za-z0-9]+$  匹配由数字和26个英文字母组成的字符串 注意\w包含下划线_  

^\w+$   匹配由数字、26个英文字母或者下划线组成的字符串      

常用数字正则和常用字符串正则,是最基本的正则应用,读者可以作为入门的练习,试试能不能快速的读懂其中的含义。  

Js代码  


匹配中文字符  

  

普遍使用的正则是[\u4e00-\u9fa5],但这个范围并不完整。例如:  

/[\u4e00-\u9fa5]/.test( '⻏' ) // 测试部首⻏,返回false  

根据Unicode 5.0版编码,要准确的判断一个中文字符要包括:  

范围  含义  范围  含义  

2E80-2EFF   CJK 部首补充    2F00-2FDF   康熙字典部首  

3000-303F   CJK 符号和标点   31C0-31EF   CJK 笔画  

3200-32FF   封闭式 CJK 文字和月份   3300-33FF   CJK 兼容  

3400-4DBF   CJK 统一表意符号扩展 A  4DC0-4DFF   易经六十四卦符号  

4E00-9FBF   CJK 统一表意符号  F900-FAFF   CJK 兼容象形文字  

FE30-FE4F   CJK 兼容形式    FF00-FFEF   全角ASCII、全角标点  

因此,正确的匹配中文字符正则表达式为:  

var rcjk = /[\u2E80-\u2EFF\u2F00-\u2FDF\u3000-\u303F\u31C0-\u31EF\u3200-\u32FF\u3300-\u33FF\u3400-\u4DBF\u4DC0-\u4DFF\u4E00-\u9FBF\uF900-\uFAFF\uFE30-\uFE4F\uFF00-\uFFEF]+/g;  

如果不希望匹配标点、符号,在正则中去掉对应的范围即可:  

3000-303F   CJK 符号和标点   FF00-FFEF   全角ASCII、全角标点  

Js代码  


匹配双字节字符(包括汉字在内)  

  

[^\x00-\xff],可以用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1),代码示例如下:  

console.info( "abc".replace( /[^\x00-\xff]/g,"aa" ).length ) // 3  

console.info( "汉字".replace( /[^\x00-\xff]/g,"aa" ).length ) // 4  

console.info( "abc汉字".replace( /[^\x00-\xff]/g,"aa").length ) // 7  

Js代码  


匹配HTML标记的正则表达式  

  

先说说网上流传的版本:  

<(\S*?)[^>]*>.*?</\1>|<.*? />  

*?  *表示0个或多个,?表示0个或1个,两个叠加起来标识0个多个,与*的功能重叠  

(\S*?)  标签的长度必须大于0,因此不能用*?   

|<.*?\/>  没有分组,无法获取以<div/>这种自关闭格式书写的标签  

</\1>  

<.*? />   有的标签是不关闭的,比如<br><hr>,因此不能强制关闭  

修正如下:  

var rtag = /^<([a-z]+)\s*\/?>.*(?:<\/\1>)?$/i  

rtag.exec( '<-div></-div>') // null   

rtag.exec( '<div>abc') // ["<div>abc", "div"]  

这个表达式也不完善,比如第二条测试语句,这么写是为了能提取中包含了文本内容的标签,如果要严格匹配,可再次修改为:  

var rtag = /^<([a-z]+)\s*\/?> (?:<\/\1>)?$/i // 去掉了中间的.*  

这个正则的应用范围仅限于简单的标签匹配、提取,不能匹配嵌套标记。  

Js代码  


匹配首尾空白字符的正则表达式  

  

先说说网上流传的版本:  

^\s*|\s*$  

可以删除行首行尾的空白字符,例如:  

'   \t    \n\r   abc   \t    \n\r   '.replace( /^\s*|\s*$/g, '' ) // abc  

但是用\s*不能判断出字符串是否在开头或结尾处有\s,例如:  

/^\s*|\s*$/.test( 'abc' ) // true  

修正如下:  

^\s+|\s+$  

'   \t    \n\r   abc   \t    \n\r   '.replace( /^\s+|\s+$/g, '' ) // abc  

/^\s+|\s+$/.test( 'abc' ) // false  

Js代码  


匹配Email地址的正则表达式  

  

先介绍下Email的规则:local-part@domain  

   local-part最长64,domain最长253,总长最长256  

   local-part可以使用任意ASCII字符:  

   大小写英文字母 a-z,A-Z  

   数字 0-9  

   字符 !#$%&'*+-/=?^_`{|}~  

   字符 .不能是第一个和最后一个,不能连续出现两次  

   但是有些邮件服务器会拒绝包含有特殊字符的邮件地址  

   domain(域名)仅限于26个英文字母、10个数字、连词号-  

   连词号-不能是第一个字符  

   顶级域名(com、cn等)长度为2到6个  

先说说网上流传的版本:  

\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*  

()  莫名奇妙的分组,如果只分组不记录,可以使用(?:)  

@\w domain不能包含下划线_  

\w+([-.]\w+)*   顶级域名不符合规则  

修正如下:  

var remail = /^([\w-_]+(?:\.[\w-_]+)*)@((?:[a-z0-9]+(?:-[a-zA-Z0-9]+)*)+\.[a-z]{2,6})$/i  

remail.exec( 'nuysoft@gmail.com' ) // "nuysoft@gmail.com", "nuysoft", "gmail.com"]  

remail.exec( 'nuysoft@gmail.comcomcom' ) // null  

remail.exec( 'nuysoft@_gmail.com ) // null  

修正后的正则有如下局限性:  

   不支持中文邮箱、中文域名,之所以不在其中支持是因为我个人的爱好倾向,反感这类华而不实的玩意  

   不支持特殊符号,避免非邮件服务器拒绝,如果需要,可以添加。  

参考文章:  
http://en.wikipedia.org/wiki/Email_address   http://baike.baidu.com/view/119298.htm  
Js代码  


匹配网址URL的正则表达式  

  

先说说网上流传的版本:  

[a-zA-z]+://[^\s]*  

粗糙,没有对URL中各个块进行分组  

修正如下(又一段网上流传的版本):  

var _url = "^((https|http|ftp|rtsp|mms)?://)?" //  

         + "(([0-9a-z_!~*'().&=+$%-]+: )?[0-9a-z_!~*'().&=+$%-]+@)?" // ftp的user@  

         + "(([0-9]{1,3}.){3}[0-9]{1,3}" // IP形式的URL- 199.194.52.184  

         + "|" // 允许IP和DOMAIN(域名)  

         + "([0-9a-z_!~*'()-]+.)*" // 域名- www.  

         + "([0-9a-z][0-9a-z-]{0,61})?[0-9a-z]." // 二级域名  

         + "[a-z]{2,6})" // first level domain- .com or .museum  

         + "(:[0-9]{1,4})?" // 端口- :80  

         + "((/?)|" // a slash isn't required if there is no file name  

         + "(/[0-9a-z_!~*'().;?:@&=+$,%#-]+)+/?)$";  

var rurl = new RegExp( _url, 'i' );  

  

测试:  

rurl.exec( 'baidu.com' ) // ["baidu.com", undefined, undefined, undefined, undefined, "baidu.com", undefined, "baid", undefined, undefined, "", "", undefined]  

rurl.exec( 'http://baidu.com' ) //   

rurl.exec( 'http://www.baidu.com' ) // ["http://baidu.com", "http://", "http", undefined, undefined, "baidu.com", undefined, "baid", undefined, undefined, "", "", undefined]  

rurl.test( 'baidu' ) // true  

看来不怎么也好用,有待学习TODO。  

Js代码  


匹配帐号是否合法  

  

先说说网上流传的版本:  

^[a-zA-Z][a-zA-Z0-9_]{4,15}$  

(字母开头,允许5-16字节,允许字母数字下划线)  

限制必须以字母开头现在看来不合适,比如QQ登录平台  

限制不能以下划线开头也没有必要,比如百度就允许,因此简单点  

修正如下:  

var ruser = /\w{4,16}/  

Js代码  


匹配国内电话号码  

  

网上流传的版本很好用:  

\d{3}-\d{8}|\d{4}-\d{7}  

评注:匹配形式如 0511-4405222 或 021-87888822  

Js代码  


匹配腾讯QQ号  

  

网上流传的版本很好用:  

 [1-9][0-9]{4,}  

评注:腾讯QQ号从10000开始  

Js代码  


匹配中国邮政编码  

  

网上流传的版本很好用:  

[1-9]\d{5}(?!\d)  

评注:中国邮政编码为6位数字  

Js代码  


匹配身份证  

  

先说说网上流传的版本:  

\d{15}|\d{18}  

d{15}  

\d{18}  可以判断,但是有些粗糙   

从身份证可以解析出地址、生日、性别等,因此特别说明一下:  

   身份证规则  

中国的身份证为15位(一代)或18位(二代),区别在于二代证只是在一代证的第七位数字前加了19和在末尾加了一位验证码  

   将15位升级为18位,并解析18位号码构成(地址、生日、性别)  

代码如下:  

function parseID(ID) {  

    if ( ID.length == 15 ) {  

        // 升级为18位  

        ID = ID.substr( 0, 6 ) + "19" + ID.substr( 6 );  

        // 前17位对应的系数  

        var rank = [  

                "7", "9", "10", "5", "8", "4", "2", "1", "6", "3", "7", "9", "10", "5", "8", "4", "2"  

        ];  

        // 前17为加权除以17后的余数对应的最后一位身份证号码  

        var last = [  

                "1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"  

        ];  

        // 加权和  

        for ( var i = 0, sum = 0, len = ID.length; i < len; i++)  

            sum += ID[ i ] * rank[ i ];  

        // 加上最后一位  

        ID += last[ sum % 11 ];  

    }  

    if ( ID.length != 18 ) return null;  

  

    var match = rid.exec( ID );  

    return match ? {  

        ID : ID,  

        area : match[ 1 ],  

        y : match[ 2 ],  

        m : match[ 3 ],  

        d : match[ 4 ],  

        sex : match[ 5 ] % 2  

    } : null;  

}  

限制:  

   这里只是解析出了地址代码,如何将代码转换为实际地址请问度娘。  

   返回对象中的sex为1(男)或0(女),并未做转换,如果页面显示需要,可以这样转换:sex ? "男" : "女"   

测试:  

console.info( parseID( "142327840821047" ) );  

console.info( parseID("142327198408210470" ) );  

参考资料:  
http://baike.baidu.com/view/118340.htm#1  
Js代码  


匹配IP地址  

  

先说说网上流传的版本:  

\d+\.\d+\.\d+\.\d+  

\d  数字没有限制  

修正如下:  

var rip = /^(?:(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\.){3}(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])$/;  

rip.test( "192.168.1.1" ) // true  

rip.test( "0.0.0.0" ) // true  

rip.test( "255.255.255.255" ) // true  

rip.test( "256.255.255.255" ) // false  

进一步增加分组:  

var rip2 = /^([01]?\d{1,2}|2[0-4]\d|25[0-5])\.([01]?\d{1,2}|2[0-4]\d|25[0-5])\.([01]?\d{1,2}|2[0-4]\d|25[0-5])\.([01]?\d{1,2}|2[0-4]\d|25[0-5])$/;  

rip2.exec( "192.168.1.1" ) // ["192.168.1.1", "192", "168", "1", "1"]  

rip2.exec( "0.0.0.0" ) // ["0.0.0.0", "0", "0", "0", "0"]  

rip2.exec( "255.255.255.255" ) // ["255.255.255.255", "255", "255", "255", "255"]  

rip2.exec( "256.255.255.255" ) // null  

JS判断只能是数字和小数点

1.文本框只能输入数字代码(小数点也不能输入)

<input onkeyup="this.value=this.value.replace(/\D/g,'')" onafterpaste="this.value=this.value.replace(/\D/g,'')">

2.只能输入数字,能输小数点.

<input onkeyup="if(isNaN(value))execCommand('undo')" onafterpaste="if(isNaN(value))execCommand('undo')">

<input name=txt1 onchange="if(/\D/.test(this.value)){alert('只能输入数字');this.value='';}">

3.数字和小数点方法二

<input type=text t_value="" o_value="" onkeypress="if(!this.value.match(/^[\+\-]?\d*?\.?\d*?$/))this.value=this.t_value;else this.t_value=this.value;if(this.value.match(/^(?:[\+\-]?\d+(?:\.\d+)?)?$/))this.o_value=this.value" onkeyup="if(!this.value.match(/^[\+\-]?\d*?\.?\d*?$/))this.value=this.t_value;else
this.t_value=this.value;if(this.value.match(/^(?:[\+\-]?\d+(?:\.\d+)?)?$/))this.o_value=this.value" onblur="if(!this.value.match(/^(?:[\+\-]?\d+(?:\.\d+)?|\.\d*?)?$/))this.value=this.o_value;else{if(this.value.match(/^\.\d+$/))this.value=0+this.value;if(this.value.match(/^\.$/))this.value=0;this.o_value=this.value}">

4.只能输入字母和汉字

<input onkeyup="value=value.replace(/[\d]/g,'') "onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[\d]/g,''))" maxlength=10 name="Numbers">

5.只能输入英文字母和数字,不能输入中文

<input onkeyup="value=value.replace(/[^\w\.\/]/ig,'')">

6.只能输入数字和英文<font color="Red">chun</font>

<input onKeyUp="value=value.replace(/[^\d|chun]/g,'')">

7.小数点后只能有最多两位(数字,中文都可输入),不能输入字母和运算符号:

<input onKeyPress="if((event.keyCode<48 || event.keyCode>57) && event.keyCode!=46 || /\.\d\d$/.test(value))event.returnValue=false">

8.小数点后只能有最多两位(数字,字母,中文都可输入),可以输入运算符号:

<input onkeyup="this.value=this.value.replace(/^(\-)*(\d+)\.(\d\d).*$/,'$1$2.$3')">

输入中文:  

  

<input type="text" onkeyup="this.value=this.value.replace(/[^\u4e00-\u9fa5]/g,'')">  

  

输入数字:  

  

<input type="text" onkeyup="this.value=this.value.replace(/\D/g,'')">  

  

输入英文:  

  

<input type="text" onkeyup="this.value=this.value.replace(/[^a-zA-Z]/g,'')">  

  

三个合在一起  

<input onkeyup="value=value.replace(/[^\w\u4E00-\u9FA5]/g, '')">  

  

只输入数字和字母  

:<INPUT class=input maxLength=12 size=15 name=username id="username" onKeyUp="value=value.replace(/[\W]/g,'')">
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息