码迷,mamicode.com
首页 > 编程语言 > 详细

23javascript正则表达式

时间:2016-07-13 17:22:20      阅读:160      评论:0      收藏:0      [点我收藏+]

标签:

javascript中的正则表达式解析
正则表达式是一个描述字符模式的对象,javascript的RegExp对象和String对象定义了使用正则表达式执行强大的模式匹配和文本教唆与替换函数的方法。


在javascript中,正则表达式是由一个RegExp对象表示的,可以使用两种方式创建RegExp对象:
一种是使用RegExp()构造函数来创建RegExp对象。


另一种是文本格式.使用javascript1.2中的新添加的一个特殊语法来创建RegExp对象,就像字符串直接量被定义为包含在引号内的字符一样,正则表达式直接量也被定义为包含在一对斜杠(/)之间的字符。所以javascript创建RegExp对象可能包含如下的代码:
var pattern=/s$/;或var pattern=new RegExp("s$");
这行代码创建一个新的RegExp对象,并将它赋给变量pattern。这个特殊的RegExp对象和所有以字母"s"结尾的字符串都匹配。


一个文本格式或正则表达式构造函数
文本格式: /pattern/flags
正则表达式构造函数: new RegExp("pattern"[,"flags"]); 
参数说明:
pattern -- 一个正则表达式文本
flags -- 如果存在,将是以下值:
g: 全局匹配
i: 忽略大小写
gi: 以上组合 
m:多行匹配  
[注意] 文本格式的参数不用引号,而在用构造函数时的参数需要引号。


1直接量字符
我们已经发现了,在正则表达式中所有的字母字符和数字都是按照字面意思与自身相匹配的.JavaScript的正则表达式还通过以反斜杠(\)开头的转义序列支持某些非字母字符.
例如,序列 "\n" 在字符串中匹配的是一个直接量换行符.在正则表达式中,许多标点符号都有特殊的含义.下面是这些字符和它们的含义:
\ f 换页符
\ n 换行符
\ r 回车
\ t 制表符
\ v 垂直制表符
\ / 一个 / 直接量
\ \ 一个 \ 直接量
\ . 一个 . 直接量
\ * 一个 * 直接量
\ + 一个 + 直接量
\ ? 一个 ? 直接量
\ | 一个 | 直接量
\ ( 一个 ( 直接量
\ ) 一个 ) 直接量
\ [ 一个 [ 直接量
\ ] 一个 ] 直接量
\ { 一个 { 直接量
\ } 一个 } 直接量
\ - 一个 - 直接量
\ XXX 由十进制数 XXX 指 定的ASCII码字符
\ Xnn 由十六进制数 nn 指定的ASCII码字符
\ cX 控制字符^X. 例如, \cI等价于 \t, \cJ等价于 \n
如果想在正则表达式中使用特殊的标点符号,必须在它们之前加上一个 "\" .


^ 匹配的是字符的开头,在多行检索中,匹配的是一行的开头
$ 匹配的是字符的结尾,在多行检索中,匹配的是一行的结尾
\b 匹配的是一个词语的边界.简而言之就是位于字符\w 和 \w之间的位置(注意:[\b]匹配的是退格符)
\B 匹配的是非词语的边界的字符


2字符类
将单独的直接符放进中括号内就可以组合成字符类.一个字符类和它所包含的任何一个字符都匹配,所以正则表达式 / [abc] / 和字母 "a" , "b" , "c" 中的任何一个都匹配.另外还可以定义否定字符类,这些类匹配的是除那些包含在中括号之内的字符外的所有字符.定义否定字符类时,要将一个 ^ 符号作为从左中括号算起的第一个字符。


正则表达式的字符类:
[...] 位于括号之内的任意字符。如:[abc]
[^...] 不在括号之中的任意字符。如:[^abc]
. 除了换行符之外的任意单个字符,等价于[^\n]
\w 任何单字字符, 等价于[a-zA-Z0-9]
\W 任何非单字字符,等价于[^a-zA-Z0-9]
\s 任何空白符,等价于[\ t \ n \ r \ f \ v]
\S 任何非空白符,等价于[^\ t \ n \ r \ f \ v]
\d 任何数字,等价于[0-9]
\D 除了数字之外的任何字符,等价于[^0-9]
[\b] 一个退格直接量(特例)
| 操作符的基本意义就是或运算。t(a|e|i|oo)n表示可以匹配tan,ten,tin,toon。
(...) 表示正则表达式中的分组.将几个项目分为一个单元。这个单元可由 *、+、?和|等符号使用,而且还可以记住和这个组匹配的字符以供此后引用使用
\n 和第n个分组所匹配的字符相匹配。分组是括号中的子表达式(可能是嵌套的)。分组号是从左到右计数的左括号数


匹配包括换行符在内的任意字符,以下为正确的任意字符正则表达式匹配规则: 
([\s\S]*) 
同时,也可以用 “([\d\D]*)”、“([\w\W]*)” 来表示。 




3表示匹配次数的符号
{n, m} 匹配前一项至少n次,但是不能超过m次
{n, } 匹配前一项n次,或者多次
{n} 匹配前一项恰好n次
? 匹配前一项0次或1次,也就是说前一项是可选的. 等价于 {0, 1}
+ 匹配前一项1次或多次,等价于{1,}
* 匹配前一项0次或多次.等价于{0,}
例如:
/\d{2, 4}/ 匹配2到4间的数字.


/\w{3} \d?/ 匹配三个单字字符和一个任意的数字.


/\s+java\s+/ 匹配字符串"java" ,并且该串前后可以有一个或多个空格.


/[^"] * / 匹配零个或多个非引号字符.




4正则表达式的属性
有关正则表达式的语法还有最后一个元素,那就是正则表达式的属性,它说明的是高级模式匹配的规则.和其它正则表达式语法不同,属性是在 / 符号之外说明的.即它们不出现在两个斜杠之间,而是位于第二个斜杠之后.javascript 1.2支持两个属性.
属性 i 说明模式匹配应该是大小写不敏感的.
属性 g 说明模式匹配应该是全局的.也就是说,执行一个全局的匹配,简而言之,就是找到所有的匹配,而不是在找到第一个之后就停止了.这两种属性联合起来就可以执行一个全局的,大小写不敏感的匹配.


静态属性
index属性。是当前表达式模式首次匹配内容的开始位置,从0开始计数。其初始值为-1,每次成功匹配时,index属性都会随之改变。


input属性。返回当前所作用的字符串,可以简写为$_,初始值为空字符串""。


lastIndex属性。是当前表达式模式首次匹配内容中最后一个字符的下一个位置,从0开始计数,常被作为继续搜索时的起始位置,初始值为-1,表示从起始位置开始搜索,每次成功匹配时,lastIndex属性值都会随之改变


lastMatch属性。是当前表达式模式的最后一个匹配字符串,可以简写为$&。其初始值为空字符串""。在每次成功匹配时,lastMatch属性值都会随之改变。 


5正则表达式的方法
test()方法
RegExp对象实例.test(字符串)
返回值:如果满足regexp那个实例中定义的正则规则,返回true;否则返回false。


exec()方法
RegExp对象实例.exec(字符串)
返回值:数组如果 exec() 找到了匹配的文本,则返回一个结果数组。否则,返回 null。此数组的第 0 个元素是首先与正则表达式相匹配的文本,如果RegExp没有分组,返回的数组只含有第0个元素;如果RegExp中存在分组那么返回数组的第 1 个元素是与 RegExpObject 的第 1 个分组相匹配的文本(如果有的话),第 2 个元素是与 RegExpObject 的第 2 个分组相匹配的文本(如果有的话),以此类推。除了数组元素和 length 属性之外,exec() 方法还返回两个属性。index 属性声明的是匹配文本的第一个字符的位置。input 属性则存放的是被检索的字符串 string。我们可以看得出,在调用非全局的 RegExp 对象的 exec() 方法时,返回的数组与调用方法 String.match() 返回的数组是相同的。


但是,当 RegExpObject 是一个全局正则表达式g时,exec() 的行为就稍微复杂一些。它会在 RegExpObject 的 lastIndex 属性指定的字符处开始检索字符串 string。当 exec() 找到了与表达式相匹配的文本时,在匹配后,它将把 RegExpObject 的 lastIndex 属性设置为匹配文本的最后一个字符的下一个位置。这就是说,您可以通过反复调用 exec() 方法来遍历字符串中的所有匹配文本。当 exec() 再也找不到匹配的文本时,它将返回 null,并把 lastIndex 属性重置为 0。
注意:如果在一个字符串中完成了一次模式匹配之后要开始检索新的字符串,就必须手动地把 lastIndex 属性重置为 0。


 
string对象方法:
match()方法:
用法:string对象.match(regexp对象)
返回值:数组
match() 方法将检索字符串 stringObject,以找到一个或多个与 regexp 匹配的文本。这个方法的行为在很大程度上有赖于 regexp 是否具有标志 g。


如果 regexp 没有标志 g,那么 match() 方法就只能在 stringObject 中执行一次匹配。如果没有找到任何匹配的文本, match() 将返回 null。否则,它将返回一个数组,其中存放了与它找到的匹配文本有关的信息。该数组的第 0 个元素存放的是匹配正则表达式的文本,如果regexp存在分组则返回数组的第 1 个元素是与 RegExpObject 的第 1 个分组相匹配的文本(如果有的话),第 2 个元素是与 RegExpObject 的第 2 个分组相匹配的文本(如果有的话),以此类推。除了这些常规的数组元素之外,返回的数组还含有两个对象属性。index 属性声明的是匹配文本的起始字符在 stringObject 中的位置,input 属性声明的是对 stringObject 的引用。


如果 regexp 具有标志 g,则 match() 方法将执行全局检索,找到 stringObject 中的所有匹配正则表达式子字符串。若没有找到任何匹配的子串,则返回 null。如果找到了一个或多个匹配子串,则返回一个数组。不过全局匹配返回的数组的内容与前者大不相同,它的数组元素中只存放的是 stringObject 中所有的匹配正则表达式子串,不存放与正则表达式中的分组匹配的子串。而且也没有 index 属性或 input 属性。
注意:在全局检索模式g下,match() 即不提供与分组匹配的文本的信息,也不声明每个匹配子串的位置。如果您需要这些全局检索的信息,可以使用 RegExp.exec()。


下面的示例演示了JavaScript中match函数方法的用法:
function MatchDemo(){
   var r, re;         // 声明变量。
   var s = "The rain in Spain falls mainly in the plain";
   re = /ain/i;    // 创建正则表达式模式。
   r = s.match(re);   // 尝试匹配搜索字符串。
   return(r);         // 返回第一次出现 "ain" 的地方。
}
本示例说明带 g 标志设置的JavaScript中match函数方法的用法
function MatchDemo(){
   var r, re;         // 声明变量。
   var s = "The rain in Spain falls mainly in the plain";
   re = /ain/ig;      // 创建正则表达式模式。
   r = s.match(re);   // 尝试去匹配搜索字符串。
   return(r);         // 返回的数组包含了所有 "ain" 
                      // 出现的四个匹配。
}


search()方法:
用法:string对象.search(regexp对象)
返回值:search 方法指明是否存在相应的匹配。如果找到一个匹配,search 方法将返回一个整数值,指明这个匹配距离字符串开始的偏移位置。如果没有找到匹配,则返回 -1.
注意:返回的只是与正则表达式查找内容匹配的第一个子字符串的位置.所以用全局搜索参数就没有意义了.


replace()方法:
用法:string对象.replace(regexp对象|字符串,"替换的字符串")
返回值:如果设置了regexp对象的全局匹配g,则全部满足的都将被替换;否则只替换第一个.返回替换后的字符串.
注意:replace中还可以接受字符串,但只替换第一个满足条件的字符串.


*************************
exec()方法和match()方法区别:
1对于没有分组的正则表达式
如果执行exec方法的正则表达式没有分组(非组就是括号括起来的内容),那么如果有匹配,他将返回一个只有一个元素的数组,这个数组唯一的元素就是该正则表达式匹配的第一个串;如果没有匹配则返回null。


下面两个alert函数弹出的信息是一样的:
var str= "cat,hat" ;
var p=/at/; //没有g属性
alert(p.exec(str))
alert(str.match(p))


都是"at"。在这种场合下exec等价于match。


但是如果正则表达式是全局匹配(g属性)的,那么以上代码结果不一样了:
var str= "cat,hat" ;
var p=/at/g; //注意g属性
alert(p.exec(str))
alert(str.match(p))


分别是
"at"
"at,at"。


因为对于没有分组的正则表达式exec永远只返回第一个匹配正则表达式的文本,而match在正则表达式指定了g属性的时候,会返回所有匹配正则表达式的文本。


2对于有分组的正则表达式
exec如果找到了匹配,而且包含分组的话,返回的数组将包含多个元素,第一个元素是找到的匹配正则表达式的字符串,之后的元素依次为该匹配中的第一、第二...个分组的字符串。(反向引用)


如下的代码将弹出"cat2,at":
var str= "cat2,hat8" ;
var p=/c(at)\d/;
alert(p.exec(str))


其中第一个元素是匹配/c(at)\d/的字符串"cat2",之后的元素是括号中匹配分组(at)的"at"。






var someText= "web2.0 .net2.0" ;
var pattern=/(\w+)(\d)\.(\d)/g;
var outCome_exec=pattern.exec(someText);
var outCome_matc=someText.match(pattern);


分析:
outCome_exec的值:pattern中的g属性对exec函数是没有任何作用的,因此exec将匹配第一个可以匹配的字串“web2.0”,作为其返回数组的第一个元素,另外由于pattern中包含三个分组((\w+)、(\d)、(\d)),因此该数组还将包含三个元素,依次是“web”、“2”、“0”,所以该exec执行后的最终结果是:["web2.0","web","2","0"]
outCome_matc的值:由于pattern是全局匹配的,因此match匹配了所有匹配正则表达式的子串,因此结果数组的值outCome_matc为["web2.0","net2.0"]。如果pattern没有g属性,那么它将与outCome_exec结果一样。


*************************












6常用的js正则表达式
javascript验证表单时常用 


"^-[0-9]*[1-9][0-9]*$"  //负整数 


/^[0-9]*[1-9][0-9]*$/     //正整数


/^[1-9]{1}[0-9]{0,1}$/    //1~99


"^-?\d+$"    //整数 


"^\d+(\.\d+)?$"  //非负浮点数(正浮点数 + 0) 


"^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$"  //正浮点数 


"^((-\d+(\.\d+)?)|(0+(\.0+)?))$"  //非正浮点数(负浮点数 + 0) 


"^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$"  //负浮点数 


"^(-?\d+)(\.\d+)?$"  //浮点数 


"^[A-Za-z]+$"  //由26个英文字母组成的字符串 


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


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


"^[A-Za-z0-9]+$"  //由数字和26个英文字母组成的字符串 


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


^[a-zA-z]+:\/\/(\\w+(-\\w+)*)(\\.(\\w+(-\\w+)*))*(\\?\\S*)?$  //url


/校验普通电话、传真号码:可以“+”开头,除数字外,可含有“-”,国家号。 
var patrn=/^([+]{0,1}(\d){1,2}[-]?)?((\d){3,4}([-]?(\d){6,9}))$/;


yyyy/mm/dd HH:mm格式的正则表达式
/^((((1[6-9]|[2-9]\d)\d{2})\/(0?[13456789]|1[012])\/(0?[1-9]|[12]\d|30))|(((1[6-9]|[2-9]\d)\d{2})\/0?2\/(0?[1-9]|1\d|2[0-8]))|(((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))\/0?2\/29\/))\s(0\d{1}|1\d{1}|2[0-3]):([0-5]\d{1})$/


yyyy/mm/dd的正则表达式
/^((((1[6-9]|[2-9]\d)\d{2})\/(0?[13456789]|1[012])\/(0?[1-9]|[12]\d|30))|(((1[6-9]|[2-9]\d)\d{2})\/0?2\/(0?[1-9]|1\d|2[0-8]))|(((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))\/0?2\/29\/))$/




yyyy-mm-dd的正则表达式
/^(?:(?!0000)[0-9]{4}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[0-9]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)-02-29)$/


yyyy-MM-dd HH:mm:ss的正则表达式
/^(?:(?!0000)[0-9]{4}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[0-9]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)-02-29)\s+([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]$/




年份0001-9999,格式yyyy-MM-dd或yyyy-M-d,连字符可以没有或是“-”、“/”、“.”的其中一个。
/^(?:(?!0000)[0-9]{4}([-/.]?)(?:(?:0?[1-9]|1[0-2])\1(?:0?[1-9]|1[0-9]|2[0-8])|(?:0?[13-9]|1[0-2])\1(?:29|30)|(?:0?[13578]|1[02])\1(?:31))|(?:[0-9]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)([-/.]?)0?2\2(?:29))$/




//时间格式hh  
PatternsDict.time_h=/^(0\d{1}|1\d{1}|2[0-3])$/;  


//时间格式hh:mm  
PatternsDict.time_hm=/^(0\d{1}|1\d{1}|2[0-3]):([0-5]\d{1})$/;  


//时间格式hh:mm:ss  
PatternsDict.time_hms=/^(0\d{1}|1\d{1}|2[0-3]):[0-5]\d{1}:([0-5]\d{1})$/;


//只匹配show,show1..show9,像"showddd"这样的字符串是不能匹配的
^show[1-9]?$




//正则表达式IP地址
var ipAddress = 20.26.43.111;  
var re =  /^([0-9]|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.([0-9]|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.([0-9]|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.([0-9]|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])$/;  
if(!re.test(ipAddress)){  
    alert("ip地址格式不正确,请修改");  
    return false;  
}  




//正则表达式验证Email格式
function testMail(mail,mess){
//验证email函数
var m=jQuery.trim($("#"+mail).attr(‘value‘));
var vm=new RegExp("^[a-zA-Z0-9]{1,}@{1}[a-zA-Z0-9]{1,}\.{1}[a-zA-Z0-9]{3,}$","i"); //主机名不带_或-
//var vm=new RegExp("^[a-zA-Z0-9]{1,}?@{1}[a-zA-Z0-9]{1,}[a-zA-Z0-9_\-]*(\.{1}[a-zA-Z0-9]{2,})+$","i");//主机名带_或-
if(mail.match(vm)){
$("#"+mail).next().remove();
}else{
$("#"+mail).next().remove();
$("#"+mail).after("&nbsp<span>"+mess+"</span>");
}
}


//正则表达式验证url格式:
function checkurl(tt){
var url="http://"+$(tt).val();
alert(url);
var reg=/^http:\/\/(\w+)([_|.|\-|\/|\\]?(\w+))*$/;
if(url.match(reg)){
alert("true");
return true;
}else{
alert("kkkk");
$(this).parent().find(":last").empty();
$(this).parent().find(":last").append("请填写正确的站点名称!");
return false;
}
}


//正则表达式验证汉字(只要输入的字符中包含汉字即为true)
function checkhanzi(tt){
var hanzi=$(tt).val();
//匹配汉字
var reg=/[^\x00-\xff]/


if(hanzi.match(reg)){
alert("true");
return true;
}else{
alert("kkkk");
$(this).parent().find(":last").empty();
$(this).parent().find(":last").append("请填写正确的站点名称!");
return false;
}
}


//正则表达式匹配关键字中不能有特殊字符
var reg=/^[^@#!%$¥&^*+-,.?\\s=\|]+$/;
if(url.match(reg)){
alert("不包含空格等特殊字符");
return true;
}else{
alert("kkkk");
$(this).parent().find(":last").empty();
$(this).parent().find(":last").append("含有特殊字符!");
return false;
}
}


//正则表达式输入的关键字必须以逗号分隔只能中文字母数字:
var reg=/^([\w\d\u4e00-\u9fa5],?)+$/;
if(url.match(reg)){
alert("true");
return true;
}else{
alert("kkkk");
$(this).parent().find(":last").empty();
$(this).parent().find(":last").append("请以逗号分隔!");
return false;
}
}




只能输入数字
function onlynumber(e){
e = window.event || e;  
var k = e.keyCode || e.which;


if ((k==110) || (k==190) || (k==46)||(k==8)|| (k>=48 && k<=57)||(k>=96 && k<=105)||(k>=37 && k<=40)||(k==189)){


}else if((k==190)||(k==110)){
if(window.event)
window.event.returnValue = false;
else
e.preventDefault();//for firefox
}else{
if(window.event)
window.event.returnValue = false;
else
e.preventDefault();//for firefox
    }
}
<input type="text" onkeydown="onlynumber(event)"/>






/**
 * 四舍五入
 * v 数值
 * e 保留小数点位数
 */
function rounddigits(v,e){
var t=1;
for(;e>0;t*=10,e--);
for(;e<0;t/=10,e++);
return Math.round(v*t)/t;
}
alert(rounddigits(12.5656565,2));

23javascript正则表达式

标签:

原文地址:http://blog.csdn.net/bin71722/article/details/51889532

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!