正则表达式,又称规则表达式。(英语:Regular Expression,在代码中常简写为regex、regexp或RE),计算机科学的一个概念。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。
日常中大多通过正则表达式来进行字符的校验,判断传入的参数是否符合我们需要的标准,如验证邮箱是否合法,手机号等,当然正则表达式也可以用于爬虫中,对爬取的页面内容中截取到我们需要的内容.
1.基本组成
一个正则表达式由数字,字母和符号组成,其中符号一般都是具有特殊的含义,而如果需要匹配指定的符号的话,需要使用 \ 进行转义.在本文中将使用js中的正则表达式的语法来进行展示(test()方法用于判断一个字符串中是否包含了该正则表达式) 如: /abcd/g 该表达式表示的是匹配字符串中是否含有'abcd' 而后面的/g表示的进行全局的匹配. 再如: /^abcd/g 这里的'^'有着特殊的含义,他表示了字符串的开始,也就是说该表达式匹配是在字符的开头为abcd如下图中的String和String2的区别
而如果要匹配字符的话使用 \ 进行转义即可如:
在上图中,对^和\都进行转义,使得匹配是能匹配到特殊的字符.
2.元字符:正则表达式中的特殊字符也叫做元字符,他们都有着各自的作用,也是因为有着这些元字符,使得正则表达式的功能更加强大
.能匹配除了换行符\n外的所有单字符,相当于[^\n]如:
/.abcd/g 能匹配 aabcd .abcd +abcd 这些字符,但是不能匹配换行符,也就是
/abcd./g 能够匹配 abcd+任意字符,但是对于 abcd\n 这个字符是不成立的,因为后面的\n并不匹配.
[]表示匹配其中包含的字符,如[a-zA-Z0-9_]表示匹配所有的字母数字相当于\w如:
/[abc]abcd/g 匹配 aabcd babcd cabcd ,能够匹配[]其中的所有字符,但是只能匹配一个 如:aeabcd是不匹配的
[^]表示否定,也就是匹配除了[]中的其他任意字符如:
/abcd[^a]/g 能够匹配 abcda abcd. abcd+ abcd\n 唯独不匹配 abcda
* 表示匹配 *前的一个字符>=0次数,通过这个元符号,我们可以控制字符重复的次数如
/a*bcd/g 能够匹配 abcd bcd aabcd aaabcd
+ 表示匹配 +前的一个字符>=1次数,他和*的区别就只在于重复的次数不能为0
/a+bcd/g 不能匹配 bcd 其他的和 /a*bcd/g 是一样的
? 表示在该元字符前面的字符为可选字符 如:
/abcd[abc]/g 是无法匹配 abcd 的,因为需要在[]选取一个字符,但是如果将原来的正则改为
/abcd[abc]?/g 那么[]中的内容变成可选的也就匹配了 abcd
{n,m} 表示匹配n到m个 { 前的字符,当只有一个参数时,表示匹配的数量必须和参数相等,第一个参数必须存,第二个参数不填时表示无穷.如:
/abcd{1,2}/g 匹配 abcd abcdd 而 /abcd{1,}/g 则能匹配 abcddd abcdddd 对于 /abcd{2}/g 指定了必须是匹配两个d也就是 abcdd
() 表示一个字符组,对于前面说到的+ * {} 等的对象都是前一个字符在有()的情况下能够是使得单字符变成多个字符.
/ab(cd)+/g 能够匹配 abcd abcdcd
而且()能与 | 一起使用使其变成类似[]的作用但还是有小许的区别
/ab(c|d)/g 匹配 abc abd /ab(cd|ef)/g 能够匹配 abcd abef
| 表示匹配 | 前面的字符串或则是后面的字符串
/abcd|ef/g 表示匹配 abcd ef
\ 用于转义元字符,使其能够被匹配到
/abcd\\/ 匹配 abcd\
^表示从开始匹配,也就是说只有在开始就符合的才能够被匹配到
/^abcd/g 能匹配到 abcdd 但却不能匹配到 babcd
$表示匹配末端,和^是相反的
/abcd$/g 匹配 abcd 不匹配 abcdd
并且^和$一起使用能够使一个匹配的字符串使完全符合正则表达式的,如:
/^abcd$/g 匹配 只能匹配abcd
3.简写字符集
一些常用的字符集可以用以下的简写表达式来代替.这里补充一个中午的正则[\u4e00-\u9fa5] 该表达式能够匹配基本汉字.
4.断言,所有的断言都是属于非捕获簇(不会对其中的文本进行捕获,也不进行组合计算),意思是在进行匹配时,不会将断言的内容匹配到结果中,只会是作为一个条件对断言后面的内容进行约束
(1)?= 正先行断言存在 ,需要与()一起使用,判断的条件放在=后面如(?=a),表示在该表达式的前一部分的后面需要有一个字母a,而在该表达式的后面则没有要求.例子如下:
/.+?(?=</div>)/g 匹配 "一 二 三 四</div>" 结果得到 "一 二 三 四" 这里因为表达式要求了匹配的结果后面需要在</div>,并且由于先行断言不会被捕获,所以结果中没有</div>,从这里我们可以知道一般情况下先行断言都是放在一个条件的后面,表示一个条件,那么如果把先行条件放在表达式的后面会怎么样呢
/(?=</div>).+/g 匹配 "一 二 三 四</div>" 结果得到的式 "</div>" 这个结果又是怎么回事呢,首先在先行断言的前面没有任何的表达式,这里先行断言还是会执行,这时定位就来到饿了</div>的"<"位置,然而应为先行断言是不进入捕获的位置的,接下来的表达是.+将匹配剩余的所有字符,也就将"</div>"整个匹配了.
(2)>! 负先行断言,同样需要与()一起使用,他的含义与正先行断言相反,需要保证前一个表达式的后面没有负先行断言的条件.例子如下
/.+四(?!</div>)/g 是无法匹配 "一 二 三 四</div>" 但是能够匹配 "一 二 三 四a</div>"
(3)?<= 正后发断言,表示匹配该表达式后面一部份时,前面需要满足正后发断言中的条件如:
/(?<=</div>).+/g 匹配 "</div>一 二 三 四a</div>" 结果返回的是 "一 二 三 四a</div>"
(4)?<! 负后发断言,与后发断言相反,匹配后一部分不存在断言中的条件
/(?<!</div>)一.+/g 匹配 "</div>一 二 三 四一</div>" 结果返回的是 "一</div>"
5.标志
用来修改正则的匹配模式,也就是我们一直使用的表达式后面的g
g表示的是全局搜索,如果没有带上g的话,那么正则在匹配到一个结果的时候就会停下,只有在带上g的情况下才会将所有的匹配项返回
i用于开启大小写忽略
m用于开启多行模式,如果要使^和$是从每一行开始的,那么就需要开启多行模式
6.贪婪模式
正则表达式默认开启的是贪婪模式,也就是尽可能多的获取符合的字符,主要是在使用+ * 的时候这时可以使用?使其变成惰性模式,也就是匹配尽可能少的字符.例如:
/.*ab/g 匹配 qewrabsdfab 时会匹配整个字符串,而使用?使其转换为惰性后
/.*?ab/g 匹配的结果时 qewrab sdfab 而不会是整个字符串