摘要:在默认的模式下,元字符和分别匹配字符串的开头和结尾处,模式改变了这俩元字符的定义,让他们匹配一行的开头和结尾。可以使用非捕获元字符或来忽略对这部分正则表达式的保存。
一、背景
工作上遇到一个这样的需求:
用正则表达式将一个字符串中的span标签替换为img标签,并将原span标签的内容放到img标签的src中,问题详细描述:点我
看到这个需求,我知道应该可以用正则表达式,可是由于之前没怎么用,一想到正则表达式就头大,一堆各种各样的特殊符号,似乎没有规律可循,有点难以理解。不过知道自己不能逃避,于是自己就去尝试怎么写这个正则表达式来解决我的需求,上述中提到的问题详细描述,大概就是我思考的过程,问题提出后立马有人解答,看完他们的答案后,惭愧,感觉到自己知识的欠缺,再不学习就老了(┬_┬)
二、正则表达式基础 2.1 元字符介绍"^":^会匹配行或者字符串的起始位置,有时还会匹配整个文档的起始位置。
"$":$会匹配行或字符串的结尾。
"b":不会消耗任何字符只匹配一个位置,常用于匹配单词边界 如:我想从字符串中"This is Regex"匹配多带带的单词 "is" 正则就要写成:"This is Regex".match(/is/); "b" 不会匹配is 两边的字符,但它会识别is 两边是否为单词的边界。
"d":匹配数字。
"w":匹配字母,数字,下划线。等价于"[A-Za-z0-9_]"。
"s":匹配空格。
".":匹配除了换行符以外的任何字符。
"[a-zA-Z]":字符组 匹配包含括号内元素的字符。
几种反义:改成大写,意思就与原来的相反。
如:
"W":匹配任何非单词字符。等价于"1"。
"2":匹配除了abc以外的任意字符。
字符转义:在正则表达式中元字符是有特殊的含义的,当我们要匹配元字符本身时,就需要用到字符转义,如:/./.test("."); // true
2.2 量词 2.2.1 常用量词"*"(贪婪)重复零次或更多,贪婪量词会首先匹配整个字符串,尝试匹配时,它会选定尽可能多的内容,如果 失败则回退一个字符,然后再次尝试回退的过程就叫做回溯,它会每次回退一个字符,直到找到匹配的内容或者没有字符可以回退。如:
"aaaaaa".match(/a*/) // ["aaaaaa"]
"?"(懒惰)重复零次或一次,懒惰量词使用另一种方式匹配,它从目标的起始位置开始尝试匹配,每次检查一个字符,并寻找它要匹配的内容,如此循环直到字符结尾处。如:"aaaaaa".match(/a?/) // ["a"]
"+"(占有)重复零次或更多次,占有量词会覆盖事个目标字符串,然后尝试寻找匹配内容 ,但它只尝试一次,不会回溯。如:
"aaaaaa".match(/a+/) // ["aaaaaa"]
"{n}" 重复n次;如:
"aaaaaa".match(/a{3}/) // ["aaa"]
"{n,m}" 重复n到m次;如:
"aaaaaa".match(/a{3,4}/) // ["aaaa"]
"{n,}" 重复n次或更多次;如:
"aaaaaa".match(/a{3,}/) // ["aaaaaa"]
"*?" 重复任意次,但尽可能少重复;如:"aabab".match(/a.*?b/) // ["aab"] 为什么第一个匹配是aab(第一到第三个字符)而不是ab(第二到第三个字符)?简单地说,因为正则表达式有另一条规则,比懒惰/贪婪规则的优先级更高:最先开始的匹配拥有最高的优先权。
"+?" 重复1次或更多次,但尽可能少重复,与上面一样,只是至少要重复1次。如:"aabab".match(/a.+?b/) // ["aab"]
"??" 重复0次或1次,但尽可能少重复。如:"aabab".match(/a.??b/) // ["aab"]
"{n,m}?" 重复n到m次,但尽可能少重复。如:"aaa".match(/a{1,3}?/) // ["a"]
"{n,}?" 重复n次以上,但尽可能少重复。如:"aaa".match(/a{1,}?/) // ["a"]
2.2.2 处理选项javascript中正则表达式支持的正则表达式有三个,g、i、m,分别代表全局匹配、忽略大小写、多行模式。三种属性可以自由组合共存。
在默认的模式下,元字符 ^ 和 $ 分别匹配字符串的开头和结尾处,模式 m 改变了这俩元字符的定义,让他们匹配一行的开头和结尾。
三、正则进阶 3.1 捕获分组正则表达式一个最重要的特性就是将匹配成功的模式的某部分进行存储供以后使用这一能力。对一个正则表达式模式或部分模式两边添加圆括号将导致这部分表达式存储到一个临时缓冲区中。(可以使用非捕获元字符 "?:", "?=", 或 "?!" 来忽略对这部分正则表达式的保存。)
所捕获的每个子匹配都按照在正则表达式模式中从左至右所遇到的内容存储。存储子匹配的缓冲区编号从 1 开始,连续编号直至最大 99 个子表达式。每个缓冲区都可以使用 "n" 访问,其中 n 为一个标识特定缓冲区的一位或两位十进制数。
后向引用一个最简单,最有用的应用是提供了确定文字中连续出现两个相同单词的位置的能力。举个例子:
/([a-zA-Z]+)s+1/.exec(" asd sf hello hello asd"); //["hello hello", "hello"]
解释这个例子:
1、(b[a-zA-Z]+b) 是一个捕获分组,它捕获所有的单词,
" asd sf hello hello asd".match(/([a-zA-Z]+)/g) // ["asd", "sf", "hello", "hello", "asd"]
注:加上/g这个处理选项是便于我理解,没有这个选项的时候,只输出第一个单词asd。
2、s加了一个空格限制条件,所以最后一个单词被排除,
" asd sf hello hello asd".match(/([a-zA-Z]+)s/g) ["asd ", "sf ", "hello ", "hello "]
3、"1"后向引用,
" asd sf hello hello asd".match(/([a-zA-Z]+)s+1/g) ["hello hello"]
说实话,这个例子花了我很长时间去理解,有一点点想通,感觉这个概念看起来容易,写起来并不容易啊。
3.2 捕获分组常有的用法(断言)"(exp)" 匹配exp,并捕获文本到自动命名的组里;如:
/(hello)sworld/.exec("asdadasd hello world asdasd") // ["hello world", "hello"]
"(?:exp)" 匹配exp,不捕获匹配的文本,也不给此分组分配组号;如:
/(?:hello)sworld/.exec("asdadasd hello world asdasd") // ["hello world"]
"(?=exp)" 用来捕获exp前面的字符,分组中的内容不会被捕获,也不分配组号;如:
/hellos(?=world)/.exec("asdadasd hello world asdasd") // ["hello "]
"(?!exp)" 捕获后面不是exp的字符,同样不捕获分组的内容,也不分配组号;如:
/hellos(?!world)/.exec("asdadasd hello world asdasd") //null world改变一下: /hellos(?!world)/.exec("asdadasd hello wosrlds asdasd") //["hello "]
"(?
/(?!四、Javascript中正则表达式的使用 在JavaScript中定义一个正则表达式语法为:
var reg=/hello/ 或者 var reg=new RegExp("hello")接着列举一下JavaScript中可以使用正则表达式的函数,并简单介绍一下这些函数的作用。
4.1 String.prototype.search方法用来找出原字符串中某个子字符串首次出现的索引index,没有则返回-1。可以在官方文档中了解更多。
"abchello".search(/hello/); // 34.2 String.prototype.replace方法用来替换字符串中的子串。简单例子:
"abchello".replace(/hello/,"hi"); // "abchi"在官方文档中有提到:
如果第一个参数是 RegExp对象,那么替换字符串可以插入特殊变量名$n,n是个小于100的非负整数,表示插入第 n 个括号匹配的字符串。
所以我在文中一开始提到的需求就可以用
4.3 String.prototype.split方法
str.replace(/(.*?)/g, "") [$1表示/(.?)/g中的“(.?)”)匹配的字符串]
答案来解答。用来分割字符串
"abchelloasdasdhelloasd".split(/hello/); //["abc", "asdasd", "asd"]4.4 String.prototype.match方法用来捕获字符串中的子字符串到一个数组中。默认情况下只捕获一个结果到数组中,正则表达式有”全局捕获“的属性时(定义正则表达式的时候添加参数g),会捕获所有结果到数组中。
"abchelloasdasdhelloasd".match(/hello/); //["hello"] "abchelloasdasdhelloasd".match(/hello/g); //["hello","hello"]4.5 RegExp.prototype.exec方法和字符串的match方法类似,这个方法也是从字符串中捕获满足条件的字符串到数组中,但是也有两个区别。
1、exec方法一次只能捕获一份子字符串到数组中,无论正则表达式是否有全局属性/hello/g.exec("abchelloasdasdhelloasd"); // ["hello"]2、正则表达式对象(也就是JavaScript中的RegExp对象)有一个lastIndex属性,用来表示下一次从哪个位置开始捕获,每一次执行exec方法后,lastIndex就会往后推,直到找不到匹配的字符返回null,然后又从头开始捕获。 这个属性可以用来遍历捕获字符串中的子串。
var reg=/hello/g; reg.lastIndex; //0 reg.exec("abchelloasdasdhelloasd"); // ["hello"] reg.lastIndex; //8 reg.exec("abchelloasdasdhelloasd"); // ["hello"] reg.lastIndex; //19 reg.exec("abchelloasdasdhelloasd"); // null reg.lastIndex; //04.6 RegExp.prototype.test方法用来测试字符串中是否含有子字符串
/hello/.test("abchello"); // true五、总结总算是对正则表达式了解了一些,要熟练掌握还需后面多多实践^_^
参考资料:
1.http://www.cnblogs.com/zery/p...
2.http://www.cnblogs.com/tzyy/p...
3.http://www.codeyyy.com/regex/...A-Za-z0-9_ ↩
abc ↩
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/92369.html
摘要:改为后,显示出文件的大概大小,单位是或者或者默认为,显示的文件时间为时间。 这是 Nginx 学习总结的第三篇,上一篇介绍到了 Nginx 学习总结(2) —— 基本配置,这一篇会对Location 模块 做一些总结。我们知道,Location 模块 主要是用于针对某些特定的 URL 进行配置,可以由前缀字符串定义,也可以由正则表达式定义。 Location 匹配规则 location...
摘要:首先推荐几个正则表达式编辑器正则表达式是一种查找以及字符串替换操作。此表所列的常用正则表达式,除个别外均未在前后加上任何限定,请根据需要,自行处理。例如对而言,则采用一对引号来确定正则表达式的边界。 这篇文章本来很早就要写的,拖了挺久的,现在整理下,供大家学习交流哈! 基本概念 正则表达式是一种文本模式,包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为元字符)。模式描述在搜...
摘要:用匹配的模式切割,第二个参数是限制返回结果的最大数量匹配规则字面量字符和元字符大部分字符在正则表达式中,就是字面的含义,比如匹配,匹配。它们叫做元字符,主要有以下几个。相比之下,点号作为元字符是不包括换行符的。 1.概述 正则表达式(regular expression)是一种表达文本模式(即字符串结构)的方法。 创建方式有两种方式: 一种是使用字面量,以斜杠表示开始和结束。 var ...
阅读 2718·2021-11-25 09:43
阅读 2098·2021-11-24 09:39
阅读 1998·2021-11-17 09:33
阅读 2769·2021-09-27 14:11
阅读 1883·2019-08-30 15:54
阅读 3238·2019-08-26 18:27
阅读 1275·2019-08-23 18:00
阅读 1824·2019-08-23 17:53