正则表达式描述了一种字符串的匹配模式,可以用来检查一个串是否含有某子串,或是特定字符串是否匹配特定规则.
换句话说就是记录文本规则的一段代码。其目的在于精确地过滤字符,找到想要的字符。
历史:正则表达式的第一个实用应用程序就是 Unix 中的 qed 编辑器 此后便被广泛用在文本搜索和匹配上
结构:正则表达式是由普通字符(例如字符 a 到 z)以及特殊字符(称为"元字符")组成的文字模式
第一小节:元字符
下面是一些常见的元字符
\b 代表单词的开头或结尾,即单词的分界.匹配的是一个位置。 'en' 很多单词都包含,women men engage ,如果想要准确地找'en'这个单词,应当使用\b来表达分界,例如:\ben\b
\d 匹配数字 例如 :0~9
\s 匹配任意空白字符
\w 匹配字母数字或下划线或汉子 例如:a-z或0~9或_或汉子
. 匹配除换行符以外的任意字符
\n 换行符
^ 匹配字符串的开始,多用在输入验证
$ 匹配字符串的结束,多用在输入验证
* 代表数量,,指定前边的内容可以连续重复使用任意次
学习正则的表达式最好的方法是从例子学习,下面将介绍大量的实例
eg : \bhi\b.*\blucy\b 解释:显示一个单词hi,中间跟任意字符,不包括换行,最后是lucy
eg: 0\d\d-\d\d\d\d\d\d\d 解释:以0开头然后两个任意数字然后-然后8位任意数字
为了避免烦人的重复可以{数字}来表达次数,有关次数在后文会详细介绍
eg: 0\d{2}-\d{8} 解释:0开始然后是两位数字,然后是-,然后是8位数字,表示必须连续出现的匹配次数,其中-并不是元字符 ,只是普通字符,匹配它本身而已
eg: ^\d{5,12}$ 解释:以数字开头,数字结尾,长度5到12位
第二小节:字符转义 \
如果想查询元字符.*本身,你没办法指定他们,这时候就要使用\来取消这些字符的特殊意义,因此,使用\.\* ,查找‘\’本身也要转义\\
eg: www.baidu.com www\.baidu\.com
eg:c:\\user c:\\\\user
第三小节:重复又称限定符 {}
类似 *,+,{2},{2,5} 都是表示次数的方式。
*:多次或0次
+:1次或多次
?:0次或1次
{n}:n次
{n,}n次或多次
{n,m}:n-m次
eg: window\d+ 解释:windows后跟一个或多个数字
eg: ^\d{m,n}$ 解释:m到n位数字
eg: \ba\w+y\b 解释: 一个以a开头,中间是1个或多个任意字符,然后是以y结尾的单词 eg: any ,
第四小节:字符类 []
如果想要查找数字字母,空白很简单因为有\w \d \s ,但是对于预定义字符集没有办法。这时可以自己定义使用字符类
[a-z] 小写字母a到z任意一个,[A-Z]大写字母A到Z任意一个。[0-9]任意一个数字,其效果与\d类似。[a-z0-9A-Z]等同于\w。
eg:[aeiou] 解释:匹配任意一个英文元音字母
eg: [,.!] 解释:匹配任意一个标点
eg:^[a-zA-Z][a-zA-Z0-9_]{4,15}$ 解释:判断帐号是否合法(字母开头,然后是字母数字下划线结尾,出现4到15次)
eg: ^[a-zA-Z]\w{5,17}$ 解释: 匹配密码(以字母开头不区分大小写,然后是字母数字下划线结尾 ,出现5到17次,与上例异曲同工)
eg:[\u4e00-\u9fa5] 解释: 匹配中文字符的正则表达式
第五小节:分支条件 |
分支条件在正则表达式里指的是有几种匹配规则 ,如果满足任意一种规则都匹配
用|把不同的规则隔开,
注意:使用分支条件是有顺序的,优先匹配到最先匹配到的分支,匹配分之是将会从左到右如果满足了某个分之就不再管其他分支 。
eg : \d{5}-\d{4}|\d{5} 解释:表达式匹配5位数字然后-然后4位数字,或者直接5位数字,
如果把分支顺序改一下则是
eg:\d{5}|\d{5}-\d{4} 解释: 如果匹配到5位数字,则后面的分支就不再进行匹配。
eg : 0\d{2}-\d{8}|0\d{3}-\d{7} 解释:匹配一种三位区号8位本地号码或是一种4位区号,7位本地号码
eg:^\d{15}|\d{18}$ 解释:×××号(15位、18位数字), 以数字开头,数字结尾,15位数字\d{15}或18位数字\d{18}
eg:^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$
解释:手机号码。遇到较长的正则表达式记住要拆开分解来看。先不看括号里的
大框架是^()\d{8}$ ()里的某些东西开头,数字结尾,共8位数字,然后是()里的内容,
就是对手机号 前三位的特殊性进行规则匹配 13[0-9],14[5|7],15[0|1|2|3|5|6|7|8|9],18[0|1|2|3|5|6|7|8|9] 就是四个分支而已。
第六小节:分组()
正则表达式用处最多的就是()了,()在正则表达式里成为分组。
分组常常和重复即限定符连起来一起使用。用以表达括号里的东西作为一个整体重复出现多少次。
eg:(\w+\d?){3} 解释:数字字母下划出现一次或多次然后出现0次或1次一个数字,这样的整体出现3次。
eg: ^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$
解释:Email地址 开头^是一次或多次+任意字符\w分组(字符类[-+.]出现-+.任意一个,
然后是一次或多次\w) 这个分组出现0次或多次,
然后是@任意多个\w接着又是
分组([-.]\w+)出现*次,然后是出现一个.然后是\w+最后是结尾$分组([-.]\w+)*
email的标准是 用户名@邮箱域名.com
有的还会有. eg:zhangsan@sina.com zhangsan.Mr.kk@sina.com
eg: ^((0?[1-9])|((1|2)[0-9])|30|31)$ 解释:一个月的31天(01~09和1~31)
eg: (\d{1,3}\.){3}\d{1,3} 解释:简单的ip地址匹配 1到3位数字然后. 这个组合出现3次最后再加一个1到3位的数字 eg:192.0.0.1
eg:((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)
解释:完整的ip4地址匹配 拆解来看结构是(){3}(),分组作为一个整体出现3次,
然后又是一个分 组。 括号里(2[0-4]\d|25[0-5]|[01]?\d\d?)继续拆分其实就
是三个分支,2[0-4]\d 200-249,25[0-5] 250-255,
[01]?\d\d? 0-9或者0-99或者199 [01] 匹配任何一个数字0,1
总体来看就是满足这三个分支任意一个都行,然后出现一个.这样的分组出现三次,
最后一个分组 一样就是不带.这 样就好理解多了。
注意:如果在正则表达式里想用()而不是分组需要转义。\(\) 代表)
eg: \(?0\d{2}\)?[ -]?\d{8}|0\d{2}[ -]?\d{8}
(011)-12345678 011-12345678 011 12345678 01112345678
第七小节:反义
eg: 想查找除了数字以外任意字符都行 这时需要用到反义
\W :匹配任意不是字母,数字,下划线,汉子的字符 大写W
\S匹配任意不是空白的字符 大写S
\D匹配任意非数字的字符 大写D
\B匹配不是单词开头或结束的位置 大写B
[^x]匹配除了x的任意字符
[^aeiou]匹配除了aeiou这几个字母以外的任意字符
\S+匹配 1个或多个不是空白的字符
eg:<a[^>]+> 解释: 匹配用尖括号括起来的以a开头除了>的一个或多个字符,即:匹配用尖括号括起来的以a开头的字符串
第八小节:正则表达式的运算符优先级
正则表达式从左到右进行计算,并遵循优先级顺序,这与算术表达式非常类似。
相同优先级的从左到右进行运算,不同优先级的运算先高后低。下表从最高到最低说明了各种正则表达式运算符的优先级顺序:
运算符 | 描述 |
---|---|
\ | 转义符 |
(), (?:), (?=), [] | 圆括号和方括号 |
*, +, ?, {n}, {n,}, {n,m} | 限定符 |
^, $, \任何元字符、任何字符 | 定位点和序列(即:位置和顺序) |
| | 替换,"或"操作 |
第九小节:后向引用 (exp) ,(?<name>exp),(?''exp)
百科下来的术语是这样解释:使用小括号指定一个子表达式后,匹配这个子表达式的文本(也就是此分组捕获的内容)可以在表达式或其它程序中作进一步的处理。默认情况下,每个分组会自动拥有一个组号,规则是:从左向右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2,以此类推。
后向引用 用于重复搜索前面某个分组匹配的文本
其核心就是捕获
(exp) exp匹配到的东西放到默认组里,后续用这个组里匹配到的东西 就用\1
(?<name>exp) exp匹配到的东西放到名为name的组里,后续用这个组里匹配到的东西 就用 \k<name>
eg: 第一种写法 \b(\w+)\b\s+\1\b 解释:\1代表分组1匹配的文本, 首先是一个单词然后是单词开始和结束之间的多余1个的字母或数字会被捕获到编号为1的分组,然后是1个或几个空白字符,最后是分组1中捕获的内容, eg summer summer
第二种写法 \b(?<word>\w+)\b\s+\K<word>\b
第三种写法 \b(?'word'\w+)\b\s+\K'word'\b
eg: 第一种写法 \b(a\w+y)\b\s+\1\b 解释:单词axxy然后被捕获放到1号组里,然后\s空格,然后是调用1号组捕获到的东西,可能就是 any any
第二种写法 \b(?<hehe>a\w+y )\b\s+\K<hehe>\b
第三种写法 \b(?'hehe'a\w+y )\b\s+\K'hehe'\b
第十小节:零宽断言(?=exp),(?<=exp)
所谓断言就是表达式exp
零宽断言就是查找指定某些内容之前或之后的内容而不包括表达式部分
(?=exp) 零宽度正预测先行断言.断言自身出现的位置之后能匹配的表达式
eg: \b\w+(?=ing\b) 解释:匹配\w+之后以ing结尾的单词但不包括ing的部分 eating 去掉ing的部分 即 eat
eg: \b[aeiou]\w+(?=ed\b) 解释: 匹配元音字母的任意一个开头,然后是任意字符,1次或多次,最后是以ed结尾的单词但不包含ed的部分, apped 去掉ed 即app
(?<=exp) 零宽度正回顾后发断言,它断言自身出现的位置的前面能匹配表达式exp
(?<=\pre)\w+\b 匹配单词以re开头但不包括re的部分 Prefixes 即 fixes
eg:(?<=\s)\d+(?=\s)
解释:(?<=\s) 零宽断言,匹配1个或多个数字,前面是(?<=\s) 但不包含空格的部分,后面是(?=\s) ,但不包含空格的部分。即以空白符间隔的数字
后向引用和零宽断言连起来使用
eg:(?<=<(\w+)>).*(?=<\/\1>)等价于 (?<=<(?<label>\w+)>).*(?=<\/\k<label>>)
解释:匹配不带属性的html标签里的内容 匹配.*前面是<1个或多个\w>,但不包含这部分,
后面是<转义\/,捕获前面分组(\w+)的内容 >但不包含这部分
eg: <p>xxxxx</p>,匹配的就是xxx这部分
第十一小节:负向零宽断言(?!exp),(?<!exp)
(?!exp)零宽度负预测先行断言
断言此位置的后面不能匹配表达式exp
eg :\d{3}(?!\d) 解释:匹配三位数字,后面不能是数字
eg: [1-9]\d{5}(?!\d) 解释:匹配开头是1到9任意一位,然后是5位数字,后面不能是数字。中国邮政编码: (中国邮政编码为6位数字)
(?<!exp)零宽度负回顾后发断言 断言此位置前面不能匹配的表达式exp
eg: \b ((?<![aeiou ]>)\w)+\b 解释:匹配不包含元音连续字符串的单词
eg: (?<![0-9])\w+ 解释: 匹配前面不是数字的字符
第十二小节:贪婪与懒惰
贪婪
正则表达式在满足整体表达式的规则下会贪婪尽可能多的匹配
eg: qweqweqwe q.*e 匹配以q开始,以e结束最多字符
会匹配到 qweqweqwe 而不是 qweqwe 或者qwe
懒惰
满足整条表达式时尽可能少的匹配,
在后面加一个?即可
*? :重复任意次,但尽可能少重复
+? :重复1次或多次,,但尽可能少重复
?? :重复0次或1次,但尽可能少重复
{n,}? :重复n次以上,但尽可能少重复
{n,m}?:重复n到m次,但尽可能少重复
eg: qweqweqwe q.*?e 匹配以q开始,以e结束最短字符.
会匹配到 qwe
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。