js正则基础概念
#### 正则表达式字符表示列表 ####
**\** : 将下一个字符标记为一个特殊字符、或一个原以字符、或一个向后引用、或一个八进制转义符。例如
"n"匹配字符"n"。"\n"匹配一个换行符。序列"\\"匹配"\",而"\("则匹配"("。
**^** : 匹配字符串的开始位置。如果设置了RegExp对象的Multiline属性,^也匹配"\n"或"\r"之后的位置
**$** : 匹配字符串的结束位置。如果设置了RegExp对象的Multiline属性,$也匹配"\n"或"\r"之前的位置
** * **:匹配前面的子表达式零次或多次。例如,"zo*"能匹配"z"以及"zoo"。*等价于{0,};
**+** : 匹配前面的表达式至少一次。例如,"zo+"能匹配"zo"以及"zoo"。等价于{1,};
**?** : 匹配前面的表达式0次或1次。例如,"do(es)?"可以匹配"do"或"does"中的"do"。?等价于{0,1};
**{n}** : n是一个非负整数。匹配确定的n次。
**{n,}** : n是一个非负整数。至少匹配n次。
**{n,m}** : m和n均为非负整数,其中n<m。最少匹配n次且最多匹配m次。
**?** : 当该字符紧跟在任何一个其他限制符(*,+,?,{n},{n,},{n,m})后面时,匹配模式是非贪婪模式的。
非贪婪模式尽可能少的匹配所搜索的字符串。例如,对于字符串"oooo","o+"将匹配所有"o",
"o+?"将匹配单个"o";
**.** : 匹配除"\n"之外的任何单个字符。要匹配包括"\n"在内的任何字符,请使用像"[.\n]"的模式。
**(pattern)** : 匹配pattern并获取这一匹配。所获取的匹配可以从产生Matches集合得到,
在VBScript中使用SubMatches集合,在jscript中则使用$0...$9属性。要匹配圆括号字符,请使用"\("或"\)"。
**(?:pattern)** : 匹配pattern但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。
例如"indust(?y:ies)"就是一个比"industy|industies"更简略的表达式;
**(?=pattern)** : 正向预查,在任何匹配pattern的字符串开始出匹配查找字符串。
这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如"Windows(?95|98|nt|2000)"能匹配
"Windows2000"中的"Windows",但不能匹配"Windows3.1"中的"Windows"。预查不消耗字符,也就是说,
在匹配发生后,在最后一次匹配之后立即开始下一次匹配搜索,而不是从包预查的字符之后开始。
**(?!pattern)** : 负向预查。"Windows(?!95|97|nt|2000)",能匹配"Windows3.5"中的Windows,
不能匹配"Windows2000"中的"Windows"。
**x|y** : 匹配x或者y
**[xyz]** : 字符集合。匹配所含的任何一个字符。例如,"[abc]"可以匹配"plain"中的"a";
**[^xyz]** : 负值字符集合。匹配未包含的任意字符。例如,"[^abc]"可以匹配"plain"中的"p";
**[a-z]** : 字符范围
**\b** : 匹配一个单词边界,也就是指单词和空格间的位置。例如:"er\b"可以匹配"never"中的"er",
但不能匹配"verb"中的"er"。
**\B** : 匹配非单词边界。"er\B"能匹配"verb"中的"er",但不能匹配"never"中的"er"
**\cx** : 匹配由x指明的控制字符。例如:\cM匹配一个Control-M或回车键。x的值必须为A-Z或者a-z之一。
否则,将c视为一个原以的"c"字符
**\d** : 匹配一个数字字符。等价于[0-9]
**\D** : 匹配一个非数字字符。等价于[^0-9]
**\f** : 匹配一个换页符。等价于\x0c和\cL
**\n** : 匹配一个换行符。等价于\x0a和\cJ
**\r** : 匹配一个回车符。等价于\x0d和\cM
**\s** : 匹配任何空白字符,包括空格、制表符、换页符等。等价于[\f\n\r\t\v]
**\S** : 匹配任何非空格符。等价于[^\f\n\r\t\v]
**\t** : 匹配一个制表符。等价于\x09和\cI
**\v** : 匹配一个垂直制表符。等价于\x0b和\cK
**\w** : 匹配包括下划线的任何单词字符。等价于"[A-Za-z0-9_]"
**\W** : 匹配任何非单词字符。等价于"[^A-Za-z0-9_]"
**\Xn** : 匹配n,其中n为16进制转义值。十六进制转义值必须为确定的两个数字长。例如,"\x41"匹配"A"。
"\x041"则等价于"\x04&1"。正则表达式中可以使用ASCII编码。
**\num** : 匹配num,其中num是一个正整数。对所获取的匹配的引用。例如,"(.)\1"匹配两个连续的相同字符。
**\n** : 标识一个八进制转义值或一个向后引用。如果\n之前至少n个获取的子表达式,则n为向后引用。
否则,如果n为八进制数字(0-7),则n为一个八进制转义值
**\nm** : 标识一个八进制转义值或一个向后引用。如果\nm之前至少有nm个获得子表达式,则nm为向后引用。
如果\nm之前至少有n个获取,则n为一个后跟文字m的向后引用。如果前面的条件都不满足,
若n和m均为八进制数字(0-7),则\nm将匹配八进制转义值nm
**\nml** : 如果n为八进制数字(0-3),且m和l均为八进制数字(0-7),则匹配八进制转义值nml
**\Un** : 匹配n,其中n是一个用四个十六进制数字表示的Unicode字符。例如,\u00A9匹配版权符号(?)
#### 正则表达式的常用匹配 ####
1.匹配非负整数(正整树数 + 0):^\d+$
2.匹配正整数 : ^[0-9]*[1-9][0-9]*$\
3.匹配非正整数(负整数 + 0) : ^((-\d+)|(0+))$
4.匹配负整数 : ^-[0-9]*[1-9][0-9]*$
5.匹配整数 : ^-?\d+$
6.匹配非负浮点数(正浮点数 + 0) : ^\d+(\.\d+)?$
7.匹配正浮点数 : ^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$
8.匹配非正浮点数(负浮点数 + 0) : ^((-\d+(\.\d+)?)|(0+(\.0+)?))$
9.匹配负浮点数 : ^(-(([0-9]+\.[0-9]*[0-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]*[1-9][0-9]*)))$
10.匹配浮点数 : ^(-?\d+)(\.\d+)?$
11.匹配由26个英文字符组成的字符串 : ^[A-Za-z]+$
12.匹配由26个英文字母及数字组成的字符串 : ^[A-Za-z0-9]+$
13.匹配由数字、26个英文字母或下划线组成的字符串 : ^\w+$
14.匹配中文字符的正则表达式 : [\u4e00-\u9fa5]
15.匹配双字节字符(包括汉字在内) : [^\x00-\xff]
16.匹配空行的正则表达式 : \n[\s| ]*\r
17.匹配HTML标记的正则表达式 : /<(.*)>.*<\/\l>|<(.*)\/>/
18.匹配首尾空格的正则表达式 : (^\s*)|(\s*$)
19.中国身份证号:(^d{15}$)|(\d{17}(?:\d\x\X)$)
20.邮箱 : ^[0-9a-zA-Z]+@(([0-9a-zA-Z]+)[.])+[a-z]{2,4}$
21.手机号 : ^(1(([35][0-9])|(47)|[8][01236789]))\d{8}$
22.手机号电话号同时验证 : (^\(?\d{3,4}[\)\-]?\d{5,10}$)|(^\[1358]d[10]$)
23.实现手机号前带86或+86的情况 : ^((\+86)|(86))?(13)\d{9}$
24.电话号码手机号码同时验证 : (^(\d{3,4}-)?\d{7,8})$|(13[0-9]{9})
25.网络链接 : (h\H)(r|R)(e|E)(f|F) *= *('|")?(\w|\\|\.)+('|"\ *|>)?
26.图片链接 : (s|S)(r|R)(c|C) *= *('|")?(\w|\\|\/|\.)+('|"| *|>)?\
27.中国电话号码(包括移动和固定电话) : (\(\d{3,4}\)|\d{3,4}-|\s)?\d{7,14}
28.中国固定电话号码 : (\(\d{3,4}\)|\d{3,4}-|\s)?\d{8}
29.中国邮政编码 : [1-9]{1}(\d+){5}
30.ip地址 : ^(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9])\.(25[0-5]|2[0-4][0-9]|
[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|
[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])$
31.简单的日期判断(yyyy/mm/dd) : ^\d{4}(\-|\/|\.)\d{1,2}\1\d{1,2}$
32.演化的日期判断(yyyy/mm/dd|yy/mm/dd) : ^(^(\d{4}|\d{2})(\-|\/|\.)\d{1,2}\3\d{1,2}$)|
(^\d{4}年\d{1,2}月\d{1,2}日$)$
33.匹配网址URL的正则表达式 : ((http|ftp|https|file):\/\/([\w\-]+
(\/[\w\u4e00-\u9fa5\-\.\.\/?\@\%\!\&=\+\~\:\#\;\,]*)?)
#### js匹配正则(test,exec,match,search,replace,split) ####
1.test 检查指定的字符串是否存在
var data = "123123";
var reCat = /123/gi;
alert(reCat.test(data));//检查字符是否存在 g 继续往下走 i 不区分大小写
2.exec 返回查询值
var data = "123,12,32,Cat,cat";
var reCat = /cat/i;
alert(reCat.exec(data));//Cat
3.match 得到查询数组
var data = "123123,213,3,231,Cat,cat";
var reCat = /cat/gi;
var arrMatches = data.match(reCat);
for(var i=0,len=arrMatches;i<len;i++){
alert(arrMatches[i]);//Cat cat
}
4.search 返回搜索位置 类似indexof
var data = "123123,234,4231,Cat,cat";
var reCat = /cat/gi;
alert(data.search(reCat));//18
5.replace 替换字符 利用正则替换
var data = "123123,21,342,Cat,cat";
var reCat = /cat/gi;
alert(data.replace(reCat,"lili"));
6.split 利用正则分割数组
var data = "123213,1232,32,21,321,Cat,cat";
var reCat = /\,/;
var arrdata = data.split(reCat);
for(var i=0,len=arrdata.length;i<len;i++){
alert(arrdata[i]);
}
#### 简单类,负向类,范围类,组合类 ####
//简单类
var data = "1l,2l,3l";
var reCat = /[123]l/gi;
var arrdata = data.match(reCat);
for(var i=0;i<arrdata.length;i++){
alert(arrdata[i]);//1l 2l 3l
}
//负向类
var data = "al,1l,2l,3l,4l";
var reCat = /[^a123]l/gi;
var arrdata = data.match(reCat);
for(var i=0;i<arrdata.length;i++){
alert(arrdata[i]);//4l
}
//范围类
var data = "l1,l2,l3,l4";
var reCat = /l[2-3]/gi;
var arrdata = data.match(reCat);
for(var i=0;i<arrdata.length;i++){
alert(arrdata[i]);//l2 l3
}
//组合类
var data = "a,b,c,w,1,2,3,5";//\u0062cf
var reCat = /[a-q1-4\n]/gi;
var arrdata = data.match(reCat);
for(var i=0;i<arrdata.length;i++){
alert(arrdata[i]);//a b c 1 2 3
}
#### js 正则表达式分组知识 ####
1.简单分组
//ex:查找字符串 MouseMouse
var data = "Ah-mousemouse";
var reCat = /Mouse{2}/gi;
var arrdata = data.match(reCat);//得到查询数组
for(var i=0;i<arrdata.length;i++){
alert(arrdata[i]);//mousemouse
}
2.复杂分组
var data = "bb ba da bad aa";
var reCat = /([bd]ad?)/gi;
var arrdata = data.match(reCat);
for(var i=0;i<arrdata.length;i++){
alert(arrdata[i]);//ba da bad dad
}//注意?的使用,0次或一次
3.反向引用
var sTomatch = "#123456789";
var reNumbers = /#(\d+)/;
reNumber.test(reNumbers);
alert(RegExp.$1);//123456789
//这个例子尝试匹配后面跟着几个或数字的#符号,并对数字进行分组以保存。在调用
test方法后,所有的反向引用都保存到了RegExp构造函数中从RegExp.$1开始,如果还有第二个反向引用,
就是RegExp.$2,以此类推。因为该数组匹配了"123456780",所以RegExp中就存储了这个字符串。
var sToChange = "1234 5678";
var reMatch = /(\d{4} \d{4})/;
var sNew = sToChange.replace(rematch,"$1","$2");
alert(sNew);//5678 1234 分组匹配
4.候选
var sToMatch1 = "red";
var sToMatch2 = "black";
var reRedOrBlack = /(red|black)/;
alert(reRedOrBlack.test(sToMatch1));//true
alert(reRedOrBlack.test(sToMatch2));//true
5.非捕获性分组
//如果要创建一个非捕获分组,只要在括号的后面加上一个问号和一个紧跟的冒号
var sToMatch = "#123456789";
var reNumbers = /#(?:\d+)/;
reNumbers.test(sToMatch);
alert(RegExp.$1);//这个例子的最后一行输出一个空字符串,因为该组是非捕获的
var sToMatch = "#123456789";
var reNumbers = /#(?:\d+)/;
alert(sToMatch.replace(reNumbers,"abcd$1"));
//正因为此,replace()方法就不能通过RegExp.$X变量来使用任何反向引用,这段代码输出的
"abcd$1"而不是八成多23456789,因为在这里并不被看成是一个反向引用。
6.前瞻:告诉正则表达式运算器向前看一些字符而不是移动位置
var sToMatch1 = "bedroom";
var sToMatch2 = "bedding";
var reBed1 = /bed(?=room)/;
var reBed2 = /bed(?!room)/;
alert(reBed1.test(sToMatch1));//true
alert(reBed2.test(sToMatch1));//false
7.边界
var sToMatch = "important word is the last one.";
var reLastWord = /(\w+)\.$/;
relastWord.test(sToMatch);
alert(RegExp.$1);//one
//假如想查找一个单词,但要它只出现在行尾,则可以使用美元符号表示它;
var sToMatch = "important word is the last one.";
var reLastWord = /^(\w+)/;
reLastWord.test(sToMatch);
alert(RegExp.$1);//important
//查找其实位置的一个或多个单词字符。遇到非单词字符则停止
var sToMatch = "important word is the last one.";
var reLastWord = /^(.+?)\b/ //不包含\n 单词边界
reLastWord.test(sToMatch);
alert(RegExp.$1);//important
//这里,正则表达式用惰性量词来制定在单词边界之前可以出现任何字符,
且可以出现一次或多次(如果使用贪婪性量词,表达式就匹配整个字符串)
var data = "first second thind fourth fifth sixth ";
var reCat = /\b(\S+?)\b/g;
var arrdata = data.match(reCat);
for(var i=0;i<arrdata.length;i++){
alert(arrdata[i]);
}//抽取单词
8.多行模式
var data = "first second thind fourth\n fifth sixth";
var reCat = /(\w+)$/gm;
var arrdata = data.match(reCat);
for(var i=0;i<arrdata.length;i++){
alert(arrdata[i]);//fourth sixth
}
#### 方法介绍 ####
1.regexp.exec(string)
exec方法是使用正则表达式最强大(最慢)的方法。如果它成功匹配了string,会返回一个数组,
数组下标为0的元素将包含正则表达式regexp匹配的子字符串,下标1的元素是分组1捕获的文本...,
以此类推,除了数组元素和length之外,exec还返回两个属性,index声明的是匹配文本的第一个
字符的位置,input属性则存放的是被检索的字符串。如果匹配失败,会返回null。在调用非全局的
regexp对象的exec方法时,返回的数组与调用方法string.match返回的数组是相同的。如果exep
带有一个g表示,事情会变得复杂,查找不是从这个字符的其实位置开始,而是从regexp.lastIndex
(初始值为0)位置开始。如果匹配成功,那么regexp.lastIndex将被设置为该匹配后的最后一个字符
的位置。这就意味着可以反复调用exec()来获得字符串中所有匹配文本,当再也找不到匹配的文本时,
它将返回null,并会重置regexp.lastIndex为0通过循环调用exec去查询一个匹配模式在一个字符串
中发生了几次,1.如果提前退出循环,再次进入循环前必须把regexp.lastIndex重置为0;
2,^因子仅匹配regexp.lastIndex为0的情况。
ex:
var str = "visit bobo bobo";
var patt = /bobo/g;
var result;
console.log("带有g标识的循环调用");
while ((result = patt.exec(str) )! = null){
console.log(result);//第一次输出["bobo",index:6,input:"visit bobo bobo"],
//第二次输出["bobo",index:11,input:"visit bobo bobo"]
//下一个匹配位置
console.log(patt.lastIndex);//第一次输出10,第二次输出15
}
console.log("非手动退出循环式regexp.lastIndex的值");
console.log(patt.lastIndex);//0
console.log("不带g标示的exec");
var patt1 = /bobo/;
var result = patt1.exec(str);
console.log(patt1.lastIndex);//不带标识的时候,每一次exec执行完毕,lastIndex都重置为0
console.log(result);//["bobo",index:6,input:"visit bobo bobo"];
2.regexp.test(string)
test方法是使用正则表达式最简单(最快)的方法,如果匹配返回true,否则返回false。r.rest(string)等同于
r.exec(string) != null.不要对这个方法运用g标示
3.string.match(regexp)
match方法让一个字符串和一个正则表达式匹配。依据g标示来决定如何进行匹配。
如果没有g标识,那么string.match(regexp)的结果与调用r.exec(string)的结果相同。仅仅执行一次匹配,如果
没有找到 任何匹配的文本,就返回null,否则返回一个数据,数组的第0个是匹配的文本,下标为1对应着捕获组1捕获
的文本,...一次类推。此外,结果还具有index和input属性。分别代表匹配开始的下标的输入的文本。
如果带有g标识,那么它执行全局检索,生成一个包含所有匹配(此时会将分组忽略,当成普通的正则处理)的数组;
若没有找到任何匹配的元素则返回null。全局匹配返回数组的内容与前者大不相同,数组中存放的是string的所有
匹配子串,也没有index属性和input属性。
ex:
//测试不带g标示的match方法
var reg = /bobo(leishao)/;
var str = "boboleishao leishaobobo boboleishao";
var result = str.match(reg);
console.log(result);//["boboleishao","leishao",index:0,input:str];
console.log(reg.lastIndex);//0
//测试带g标识的match方法
var reg1 = /bobo(leishao)/g;
var str1 = "boboleishao leishaobobo boboleishao";
var result1 = str1.match(reg1);
console.log(result);//["boboleishao",'boboleishao']
console.log(reg1.lastIndex);//0
//在jQuery中使用这种方法,将一个或多个空格分开的字符串切割成一个数组
var rnotwhite = /\S+/g;
var teststr = "bobo leishao bobo";
console.log(teststr.match(rnowhite));//["bobo","leishao","bobo"]
4.string.replace(searchValue,replaceValue)
string.replace方法对string进行查找和替换操作,并返回一个新的字符串。
searchValue 1.如果是字符串,那么只会在第一次出现的时候替换;2.如果是一个正则表示式,
并且带有g标识,那么它会替换所有的匹配,如果没有g标识,它仅替换首个匹配。
a.如果replaceValue一个字符串,字符串$具有特殊含义
$$替换$;
$&替换整个匹配的文本;
$number匹配捕获的分组;
$匹配之前的文本
$'匹配之后的文本
b.如果replace是一个函数,那么每遇到一次匹配都会调用一次,函数的返回值将会作为替换文本,
传递给函数的第一个参数是整个被匹配的文本,第二个参数是分组1捕获的文本,以此类推...并且数组最后
有两个参数,一个匹配开始的位置,一个参数是输入文本
ex:
//测试replace文本
var str = "leisaho bobo leishao";
//不含有g标识的正则
console.log(str.replace(/leishao/,"shaoxianlei"));//"shaoxianlei bobo leishao"
//含有g标识的正则
console.log(str.replace(/leishao/g,"shao"));//"shao bobo shao";
//$的特殊意义
console.log(str.replace(/(\w+)\s+(\w+)/,"$2 $1"));//bobo leishao leishao
//测试第二个参数是函数
var str = "leishao bobo leishao bobo";
console.log(str.replace(/(\w+)\s+(\w+)/,function(all,str1,str2){
console.log(all);//leisho bobo
console.log(str1);//leishao
console.log(str2);//bobo
return all.toUpperCase();//LEISHAO BOBO leishao bobo
}));
//如果是带有g标识,并且第二个参数是函数
console.log(str.replace(/(\w+)\s+(\w+)/g,function(all,str1,str2){
console.log(all);//调用两次,两次都输出leishao bobo
console.log(str1);//调用两次,都输出leishao
console.log(str2);//调用两次,都输出bobo
console.log(arguments);//调用两次,第一次输出["leishao bobo","leishao","bobo",0,"leishao bobo leishao bobo"];
第二次输出["leishao bobo","leishao","bobo",13,"leishao bobo leishao
bobo"]
return all.toUpperCase();//LEISHAO BOBO LEISHAO BOBO
}));
console.log("没有分组的情况");
//如果正则中没有分组,第二个参数是函数
console.log(str.replace(\/\w+\s+\w+/g,function(all,str1,str2){
console.log(all);调用两次
console.log(arguments);//调用两次,第一次输出["leishao bobo",0,"leishao bobo leishao bobo"];第二次输入["leishao bobo",13,"leishao bobo leishao bobo"]
return all.toUpperCase();
})) ;
5.string.split(seperator,limit)
该方法用于将一个字符串分割为字符串数组。seperator必须,为字符串或正则,当是正则表达式时,该方
法或略g标识,
limit可选,该参数可以指定返回数组的最大长度
a.如果seperator是空字符串,那么返回一个单字符的数据
b.如果是正则表达式,会忽略g标识;如果正则表达式包含分组,那么分组捕获的文本会包含在分割后的数
组中
1.如果seperator是空字符串
var digits = "12345";
console.log(str.split(""));//["1","2","3","4","5"]
var str = "a|b|c|";
console.log(str.split("|"));/["a","b","c",""];
var text = "last, first,middle";
console.log(str.split(/\s*,\s*/));//["last","first","middle"]
//需要注意的是,来自分组的文本会被包含在被分割的数组中
console.log(text.split(/\s*(,)\s*/));//["last",",","first",",","middle"]
6.sting.search(regexp)
search方法用于检索字符串中指定的子字符串,或者检索与正则表达式相匹配的子字符串,如果检测不到,
返回-1
1.参数regexp可以是子字符串,这时候感觉使用IndexOf更方便一些
2.regexp可以是正则表达式对象,这时候会忽略g标识;如果要执行忽略大小写的检索,可以加上i标
识
var regexp = /\w+\s*,\s*\w+/i;
console.log("bobo leishao ,bobo".search(regexp));//5
浙公网安备 33010602011771号