正则表达式

xiaoxiao2021-02-28  110

正则表达式就是记录文本规则的代码。只不过比起通配符,它能更精确地描述你的需求

1、元字符

常用的元字符

代码 说明 . 匹配除换行符以外的任意字符 \w 匹配字母或数字或下划线或汉字,,等价于[a-z0-9A-Z_](如果只考虑英文的话) \s 匹配任意的空白符 \d 匹配数字,等价于[0-9] \b 匹配单词的开始或结束 ^ 匹配字符串的开始 $ 匹配字符串的结束

2、重复(限定符) 常用的限定符

代码/语法 说明 * 重复零次或更多次,任意数量的不包含换行的字符 + 重复一次或更多次 ? 重复零次或一次 {n} 重复n次 {n,} 重复n次或更多次 {n,m} 重复n到m次

懒惰限定符

代码/语法 说明 *? 重复任意次,但尽可能少重复 +? 重复1次或更多次,但尽可能少重复 ?? 重复0次或1次,但尽可能少重复 {n,m}? 重复n到m次,但尽可能少重复 {n,}? 重复n次以上,但尽可能少重复

例子

1、精确地查找hi这个单词 \bhi\b 2、先是单词hi,然后是任意个任意字符(但不能是换行),最后是Lucy这个单词 \bhi\b.*\bLucy\b 3、以0开头,然后是两个数字,然后是一个连字号“-”,最后是8个数字 0\d{2}-\d{8} \d必须连续重复匹配2次(8次) 4、匹配刚好6个字符的单词 \b\w{6}\b 5、QQ号必须为5位到12位数字 \d{5,12}\d 6、匹配最长的以a开始,以b结束的字符串,称为贪婪匹配。 a.*b 7、匹配最短的,以a开始,以b结束的字符串 a.*?b 8、 \(?0\d{2}[) -]?\d{8} 解析:首先是一个转义字符\(,它能出现0次或1次(?),然后是一个0,后面跟着2个数字(\d{2}),然后是)或-或空格中的一个,它出现1次或不出现(?),最后是8个数字(\d{8})。 匹配到不符合的:(012-90998908或者010)19092345 修改 \(0\d{2}\)[- ]?\d{8}|0\d{2}[- ]?\d{8} 9、 [a-z]是指小写字母中的一个字符 [A-Z]是指大写字母中的一个字符 [0-9]是指数字中的一个字符 [a-zA-Z0-9_-]是指大小写字母、数字、下划线、横线中的一个字符 [a-z][A-Z][0-9]是指三个字符,其中第一个是小写字母,第二个是大写字母,第三个是数字

3、字符转义   \ 取消元字符的特殊意义

要查找\本身,用\\ 要查找*本身,用\* 要查找(本身,用\(

4、反义:查找不属于某个能简单定义的字符类的字符

常用的反义代码

代码/语法 说明 \W 匹配任意不是字母,数字,下划线,汉字的字符 \S 匹配任意不是空白符的字符 \D 匹配任意非数字的字符 \B 匹配不是单词开头或结束的位置 [^x] 匹配除了x以外的任意字符 [^aeiou] 匹配除了aeiou这几个字母以外的任意字符

例子:

匹配用尖括号括起来的以a开头的字符串 <a[^>]+> 注意:<a+>会匹配到<aaa>like>

5、分枝条件 满足其中任意一种规则都应该当成匹配,具体方法是用|把不同的规则分隔开,从左到右地测试每个条件,如果满足了某个分枝的话,就不会去再管其它的条件了,注意顺序

美国邮编的规则是5位数字,或者用连字号间隔的9位数字 \d{5}-\d{4}|\d{5} 只会匹配5位的邮编(以及9位邮编的前5位) \d{5}|\d{5}-\d{4}

6、分组 重复单个字符(直接在字符后面加上限定符就行了);但如果想要重复多个字符又该怎么办?你可以用小括号来指定子表达式(也叫做分组),然后你就可以指定这个子表达式的重复次数了,你也可以对子表达式进行其它一些操作 默认情况下,每个分组会自动拥有一个组号,规则是:从左向右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2,以此类推。

常用分组语法 分类 代码/语法 说明 捕获 (exp) 匹配exp,并捕获文本到自动命名的组里 (?<name>exp) 匹配exp,并捕获文本到名称为name的组里,也可以写成(?'name'exp) (?:exp) 匹配exp,不捕获匹配的文本,也不给此分组分配组号 零宽断言 (?=exp) 匹配exp前面的位置 (?<=exp) 匹配exp后面的位置 (?!exp) 匹配后面跟的不是exp的位置 (?<!exp) 匹配前面不是exp的位置 注释 (?#comment) 这种类型的分组不对正则表达式的处理产生任何影响,用于提供注释让人阅读 简单的IP地址匹配 (\d{1,3}\.){3}\d{1,3} 分析:\d{1,3}匹配1到3位的数字,(\d{1,3}\.){3}匹配三位数字加上一个英文句号(这个整体也就是这个分组)重复3次,最后再加上一个一到三位的数字(\d{1,3})。匹配到不符合的260.333.222.999 使用冗长的分组 描述一个正确的IP地址:255.255.255.255 ((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?) 25[0-5] 代表250~255范围 2[0-4]\d 代表240~249范围 [01]\d\d? 代表0~9或10~19或100~199的范围 语法(?#comment)来包含注释。例如:2[0-4]\d(?#200-249)|25[0-5](?#250-255)|[01]?\d\d?(?#0-199)。

7、反向引用 后向引用用于重复搜索前面某个分组匹配的文本。例如,\1代表分组1匹配的文本

匹配重复的单词,像go go \b(\w+)\b\s+\1\b 指定子表达式的组名。要指定一个子表达式的组名,请使用这样的语法:(?<Word>\w+)(或者把尖括号换成'也行:(?'Word'\w+))

反向引用这个分组捕获的内容,你可以使用\k

匹配重复的单词,像go go \b(?<Word>\w+)\b\s+\k<Word>\b。

8、零宽断言 用于查找在某些内容(但并不包括这些内容)之前或之后的东西,也就是说它们像\b,^,$那样用于指定一个位置,这个位置应该满足一定的条件(即断言),因此它们也被称为零宽断言

(?=exp) 匹配exp前面的位置 (?<=exp) 匹配exp后面的位置 匹配以'a'间隔的数字(再次强调,不包括'a'字符) 匹配a字母前面两个数字 \d+(?=\a)

9、负向零宽断言 查找不是某个字符或不在某个字符类里的字符的方法(反义)。但是如果我们只是想要确保某个字符没有出现

(?!exp) 匹配后面跟的不是exp的位置 (?<!exp) 匹配前面不是exp的位置 \b\w*q[^u]\w*\b匹配包含后面不是字母u的字母q的单词。但是如果多做测试(或者你思维足够敏锐,直接就观察出来了),你会发现,如果q出现在单词的结尾的话,像Iraq,Benq,这个表达式就会出错。这是因为[^u]总要匹配一个字符,所以如果q是单词的最后一个字符的话,后面的[^u]将会匹配q后面的单词分隔符(可能是空格,或者是句号或其它的什么),后面的\w*\b将会匹配下一个单词,于是\b\w*q[^u]\w*\b就能匹配整个Iraq fighting。负向零宽断言能解决这样的问题,因为它只匹配一个位置,并不消费任何字符。现在,我们可以这样来解决这个问题:\b\w*q(?!u)\w*\b。 匹配除a字母外前面两个数字,如11b,22c等 \d{2}(?!a)

补充:

(?:exp) 非捕获组,匹配exp的内容,但不捕获到组里 至于作用,一般来说是为了节省资源,提高效率 比如说验证输入是否为整数,可以这样写 ^([1-9][0-9]*|0)$ 这时候我们需要用到()来限制“|”表示“或”关系的范围,但我们只是要判断规则,没必要把exp匹配的内容保存到组里,这时就可以用非捕获组了 ^(?:[1-9][0-9]*|0)$ 以上只是一个简单的例子,或许会觉得无所谓,但是如下的日期正则,如果全都用捕获组,那就是对资源的极大浪费了 ^(?:(?:(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00)))([-/.])(?:0?2\1(?:29)))|(?:(?:(?:1[6-9]|[2-9]\d)?\d{2})([-/.])(?:(?:(?:0?[13578]|1[02])\2(?:31))|(?:(?:0?[13-9]|1[0-2])\2(29|30))|(?:(?:0?[1-9])|(?:1[0-2]))\2(?:0?[1-9]|1\d|2[0-8]))))$

参考: http://www.jb51.net/tools/zhengze.html

转载请注明原文地址: https://www.6miu.com/read-54786.html

最新回复(0)