with (javascript)
前一篇浅入正则(一)了解了实例化一个RegExp对象、RegExp的原型方法、RegExp的对象属性这些基础,大致知道正则怎么用,这一篇主要想了解一下正则怎么写。
元字符
元字符表随便就查得到,但这是会写正则最重要的基础,这里简单分成两类并按我的理解简单注释。
运算符 & 限定符
{ "\": "除语义类元字符中的使用,\ 为转义字符,比如想要匹配一个'(',直接使用'('会被认作分组的开始,需要使用\转义, '/\(/'","^": { "开头": "在非'[]'中使用,表示匹配开头的意思,如果RegExp对象设置多行(m)属性,也会匹配换行符\n及\r之后的位置","非": "在'[]'中,表示取反,例如:'/[^a]/',表示匹配不是a的字符" },"$": "匹配结束的位置,如果RegExp对象设置多行(m)属性,也会匹配换行符\n及\r之前的位置","*": "任意的意思,表示匹配前面紧接着的子表达式0次或多次","+": "表示匹配前面紧接着的子表达式1次或多次,也就是最少1次","?": { 1: "表示匹配前面紧接着的子表达式0次或1次,也就是最多1次",2: "非贪婪模式:前提是紧跟在其他限定符后面,比如'*'、'+'、'{n,m}'等,表示尽可能少的匹配,比如'{n,m}',例如: '/\d{4,6}?/g',假如使用这个正则test一段字符串'123456abc',则会尽可能少的匹配,也就是每次test只匹配4个,然后lastIndex被置为4,默认情况下为贪婪模式,每次会匹配6个,lastIndex会重置为6,如果无法匹配6个才会尝试匹配5个,4个" },"{n}": "表示匹配前面紧接着的子表达式n次,n为非负整数","{n,}": "表示匹配前面紧接着的子表达式n次或更多次,也就是最少n次,n为非负整数",m}": "表示匹配前面紧接着的子表达式n次到m次,也就是最少匹配n次,最多匹配m次,n <= m 且n和m均为非负整数",".": "除'\n'外的任意字符","|": "或,例如'/a|bcd/'可以匹配'a'或者'bcd','/(a|b)cd/'可以匹配'acd'或者'bcd'","-": "仅当在'[]'中可以表示连接符,'/[a-z]/'、'/A-Z/'、'/0-9/'分别表示a到z、A到Z、0到9,其他时间就表示中划线","[]": "字符集合,表示中括号中的任意字符,比如'/[acb123ABC]/'表示匹配到'acb123ABC'中任意一个就可以","()": "分组,和我们平常的加减运算中的()差不多,可以理解为确定优先级的意思,不过js正则中的()分组可以通过'$1 - $9'获取匹配结果中,每一个分组对应的匹配值,也就是'$1'也就是第一个分组的子表达式匹配成功的结果,例如:'abc123ef'.replace(/(\w)(\d){3}/g,'$2$1'),例子中,匹配(一个字母)紧接着(一个数字)循环了三次,'$1'就是后面紧接着数字的一个字母,也就是'c','$2'就是一个数字,也就是'(\d)'的最后一个匹配结果'3',因为数字循环了三次,所以三个数字会被替换成'$1',而c会被替换成'$2',结果就是'ab3cef'","(?:)": "和()差不多一个意思,只是()中的分组内容不会被存储到'$1 - $9'的集合中","(?=)": "正向前瞻,也就是前面的表达式紧接着的表达式,要符合(?=)的=后面跟着的表达式,例如:'/[a-z](?=\d)/',只会匹配后面紧接着数字的小写字母,但是数字并不会出现在匹配结果中且不会被存储到'$1 - $9'的集合中","(?!)": "负向前瞻,也就是前面的表达式紧接着的表达式,要符合(?!)的 != 后面跟着的表达式,例如:'/[a-z](?!\d)/',只会匹配后面紧接着不是数字的小写字母,但是数字并不会出现在匹配结果中且不会被存储到'$1 - $9'的集合中" }
基础的运算符和限定符无非就这几个,说到运算符就有优先级,上面的运算符的优先级为:
{ "一级": "'\'","二级": "'()'、'(?:)'、'(?=)'、'[]'","三级": "'*'、"+"、'?'、'{n}'、'{n,}'、'{n,m}'","四级": "'^'、'$'、'其他元字符及字符'","五级": "'|'",}
语义类元字符
{ "\b": "单词边界,也就是前面或者后面要跟着个空格","\B": "非单词边界,也就是必须在单词中间,前后不能有空格","\d": "匹配一个数字字符,等价于'[0-9]'","\D": "匹配一个非数字字符,等价于'[^0-9]'","\w": "匹配任意单词字符和下划线'_',等价于'[a-zA-Z0-9_]'","\W": "匹配任意非单词字符及非下划线,等价于'[^a-zA-Z0-9_]'","\s": "匹配任意空白字符,含空格、制表符、换页符等","\S": "匹配非空白字符",//···还有很多不常用的,用时再查吧 }
前一篇笔记只解析了RegExp对象的原型方法,但是对于正则表达式,一些字符串的方法同样可以使用在正则上。
replace
replace也属于经常使用的一个方法,在具体到和正则表达式一起使用时是:stringObject.replace(RegExpObject,string|function)
,上例子:
var str1 = "2017-07-12"; var reg1 = /(\d{4})-(\d{2})-(\d{2})/g; str1.replace(reg1,function(a,b,c,d,e){ // a/b/c/d/e分别代表: 匹配结果/第一个分组匹配值/第二个分组匹配值/第三个分组匹配值/匹配成功的第一个字符的index值 console.log(a,d); //2017-07-12 2017 07 12,0 return c + "/" + d + "/" + b; }) console.log(str1); //07/12/2017
match
math方法也是string的方法,match方法用法和exec很相似,同样返回数组。
var reg1 = /([a-zA-Z]\d)+([\u4e00-\u9fa5])+/; //匹配 (大小写字母连着一个数字) 至少一次 (再连着汉字) 至少一次 var str1 = "a11B2老cd3李e45好"; var result = str1.match(reg1); console.log(result); //["B2老","B2","老"]
这个结果和exec的结果完全一样;
var reg2 = /([a-zA-Z]\d)+([\u4e00-\u9fa5])+/g; //匹配 (大小写字母连着一个数字) 至少一次 (再连着汉字) 至少一次 var str2 = "a11B2老cd3李e45好"; var result1 = str2.match(reg2); var result2 = str2.match(reg2); var result3 = str2.match(reg2); console.log(result1,result2,result3); //["B2老","d3李"] ["B2老","d3李"] console.log(result1.index,result2.input,result3); //undefined undefined ["B2老","d3李"] 执行多次均只输出每一个匹配完整正则的子字符串,同时也没有index和input的属性。
search
search方法返回的就是正则第一次匹配成功的开始位置,用法是stringObject.search(regexp);
同时serch方法只需要匹配成功一次,不会重置laseIndex属性,每次都从字符串起始位置开始搜索,也会忽略全局搜索g
:
var reg3 = /([a-zA-Z]\d)+([\u4e00-\u9fa5])+/g; var reg4 = /([a-zA-Z]\d)+([\u4e00-\u9fa5])+/g; var str3 = "a11B2老cd3李e45好"; str3.search(reg3); //3 str3.search(reg3); //3 str3.search(reg4); //3 str3.search(reg4); //3 多次搜索和是否全局均不会影响搜索结果
不管多么复杂的正则,都是用本节中的元字符写出来的,而在复杂的正则,用法无非也就上节和这一节中所记录的方法。关键在于常用才能熟练,深入才能理解。这两节笔记只是浅入,在实践中摸索实践才能真的深入浅出,一起加油。
原文链接:https://www.f2er.com/regex/358195.html