资讯专栏INFORMATION COLUMN

浅入正则(二)

MRZYD / 2697人阅读

摘要:前一篇浅入正则一了解了实例化一个对象的原型方法的对象属性这些基础,大致知道正则怎么用,这一篇主要想了解一下正则怎么写。

with (javascript)

前一篇浅入正则(一)了解了实例化一个RegExp对象、RegExp的原型方法、RegExp的对象属性这些基础,大致知道正则怎么用,这一篇主要想了解一下正则怎么写。

元字符

元字符表随便就查得到,但这是会写正则最重要的基础,这里简单分成两类并按我的理解简单注释。

运算符 & 限定符

{
    "": "除语义类元字符中的使用, 为转义字符,比如想要匹配一个"(",直接使用"("会被认作分组的开始,需要使用转义, "/(/"",
    "^": {
        "开头": "在非"[]"中使用,表示匹配开头的意思,如果RegExp对象设置多行(m)属性,也会匹配换行符
及
之后的位置",
        "非": "在"[]"中,表示取反,例如:"/[^a]/",表示匹配不是a的字符"
    },
    "$": "匹配结束的位置,如果RegExp对象设置多行(m)属性,也会匹配换行符
及
之前的位置",
    "*": "任意的意思,表示匹配前面紧接着的子表达式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为非负整数",
    "{n,m}": "表示匹配前面紧接着的子表达式n次到m次,也就是最少匹配n次,最多匹配m次,n <= m 且n和m均为非负整数",
    ".": "除"
"外的任意字符",
    "|": "或,例如"/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": "非单词边界,也就是必须在单词中间,前后不能有空格",
    "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,b,c,d);                //2017-07-12 2017 07 12,0
    return c + "/" + d + "/" + b;
})
console.log(str1);                       //07/12/2017

需要注意的是,string是没有replaceAll的方法的,需要全局替换请在正在中设置全局属性g

match

math方法也是string的方法,match方法用法和exec很相似,同样返回数组。

非全局正则调用,输出结果和exec相似,无匹配结果则返回null,有则返回数组,分别存放每一个子表达式匹配的结果,同时具有index和input两个属性:

var reg1 = /([a-zA-Z]d)+([u4e00-u9fa5])+/;
//匹配 (大小写字母连着一个数字) 至少一次 (再连着汉字) 至少一次
var str1 = "a11B2老cd3李e45好";
var result = str1.match(reg1);
console.log(result);                     //["B2老", "B2", "老"]

这个结果和exec的结果完全一样;

全局正则调用,数组只存放所有匹配的整个正则的子字符串,而不存放正则子表达式匹配的子字符串,也没有index和input的属性:

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李"] ["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.ucloud.cn/yun/87120.html

相关文章

  • 浅入正则(一)

    摘要:例在第行中,结果为,因为第四行中的匹配成功后,为,也就是下一次是从开始匹配,所以匹配失败,返回,并把置为浅入正则二字符的含义和使用 正则表达式一直作为我的痛点,没有系统的学习和了解,之前部门有本500多页的书叫《精通正则表达式》,一直没勇气拿起来。到后来业务中需要正则的地方越来越多,不忍心老找人帮忙写正则了。找了资料先看着,至少自己先入个门。 with (javascript) 实例化...

    zhaofeihao 评论0 收藏0
  • js基础常用知识点由浅入深整理篇

    摘要:因为同一时间,只能处理一个异步,这又牵扯到单线程问题了。然后控制台默默打印了个目前前端,异步主要为前后端交互以及定时器,仅仅说前端,如果说的话,还有文件读取等其他的方面会异步。 此篇文章完全按照我个人理解去写。 1.何为JS 先说说js干啥的。不负责点说,js就是操作浏览器的。 有人可能说nodeJS,nodeJS严格意义上只能说是用的ES,因为他没有dom ,也没有bom。 简单点说...

    Zack 评论0 收藏0
  • 浅入深laravel教程附录1:全局助手函数之字符串部分

    摘要:一静态属性缓存部分由于每次正则替换费时,所以有个动物函数,框架使用静态属性保存,提高效率的意思是大驼峰式,这个函数是将转换成的意思骆驼,这个函数是小驼峰格式,第一个字母是小写字母转换成的意思是蛇,很形象,整个身子都一样粗,它只对中有大写 一:静态属性缓存部分 由于每次正则替换费时,所以有4个动物函数,框架使用静态属性保存,提高效率 01:Str::studly($value)studl...

    sushi 评论0 收藏0
  • SegmentFault 技术周刊 Vol.16 - 浅入浅出 JavaScript 函数式编程

    摘要:函数式编程,一看这个词,简直就是学院派的典范。所以这期周刊,我们就重点引入的函数式编程,浅入浅出,一窥函数式编程的思想,可能让你对编程语言的理解更加融会贯通一些。但从根本上来说,函数式编程就是关于如使用通用的可复用函数进行组合编程。 showImg(https://segmentfault.com/img/bVGQuc); 函数式编程(Functional Programming),一...

    csRyan 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<