正则表达式
元字符
元字符是功能性的匹配符号, 如:\b
单词的开头或结尾,也就是单词的分界处*
匹配任意数量的字符.
匹配除了换行之外的所有字符\d
匹配0到9单个数字\s
匹配任意的空白符,包括空格,制表符(Tab),换行符,中文全角空格等\w
匹配 字母 或 数字 或 下划线 或 汉字 等^
匹配字符串的开始$
匹配字符串的结束
例子
\ba\w*\b
匹配以字母a开头的单词——先是某个单词开始处(\b),然后是字母a,然后是任意数量的字母或数字(\w),最后是单词结束处(\b)0\d\d-\d\d\d\d\d\d\d\d
匹配这样的字符串:以0开头,然后是两个数字,然后是一个连字号“-”,最后是8个数字, 简写成0\d{2}-\d{8}
, {}
是限定符^\d{5,12}$
QQ号必须为5位到12位数字 {5,12}表示次数不能少于5次,不能多于12次\d+
匹配1个或更多连续的数字。这里的+
是和`类似的元字符,不同的是
*匹配重复任意次(可能是0次),而
+则匹配重复1次或更多次
\b\w{6}\b` 匹配刚好6个字符的单词。
字符转意
查找元字符本身的话,比如你查找.
,或者*
,就出现了问题:你没办法指定它们,因为它们会被解释成别的意思。这时你就得使用\
来取消这些字符的特殊意义。因此,你应该使用\.
和\*
。当然,要查找\
本身,你也得用\\
重复
符号 | 表示 |
---|---|
* | 重复零次或更多次 |
+ | 重复一次或更多次 |
? | 重复零次或一次 |
{n} | 重复n次 |
{n,} | 重复n次或更多次 |
{n,m} | 重复n到m次 |
字符类
[ ]
集合查找 ,比如 [abcde]
表示匹配里面包含的字符 , 常见的[0-9]
和\d
等价, 即匹配一位数字, [a-z0-9A-Z_]
也完全等同于\w
(如果只考虑英文的话)\(?0\d{2}[) -]?\d{8}
首先是一个转义字符\(
,它能出现0次或1次?
,然后是一个0,后面跟着2个数字\d{2}
,然后是)
或-
或空格
中的一个,它出现0次或1次?
,最后是8个数字\d{8}
分枝条件
上面那个表达式也能匹配010)12345678或(022-87654321这样的“不正确”的格式。
正则表达式里的分枝条件指的是有几种规则,如果满足其中任意一种规则都应该当成匹配,具体方法是用|
把不同的规则分隔开。0\d{2}-\d{8}|0\d{3}-\d{7}
表示0开头接两位数字,-
后面连着8位数的电话号码,比如020-12345678 或者 0开头接三位数字,-
后面连着7位数的电话号码,比如0751-1234567
使用分枝条件时,要注意各个条件的顺序。原因是匹配分枝条件时,将会从左到右地测试每个条件,如果满足了某个分枝的话,就不会去再管其它的条件了。
分组
如果想要重复多个字符又,你可以用小括号来指定子表达式(也叫做分组)(\d{1,3}\.){3}\d{1,3}
是一个简单的IP地址匹配表达式。要理解这个表达式,请按下列顺序分析它:\d{1,3}
匹配1到3位的数字,(\d{1,3}\.){3}
匹配三位数字加上一个英文句号(这个整体也就是这个分组)重复3次,最后再加上一个一到三位的数字(\d{1,3})
。
正则表达式中并不提供关于数学的任何功能,所以只能使用冗长的分组,选择,字符类来描述一个正确的IP地址:((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)
反义
有时需要查找不属于某个能简单定义的字符类的字符。比如想查找除了数字以外,其它任意字符都行的情况,这时需要用到反义:
符号 | 表示 |
---|---|
\W | 匹配任意不是字母,数字,下划线,汉字的字符 |
\S | 匹配任意不是空白符的字符 |
\D | 匹配任意非数字的字符 |
\B | 匹配不是单词开头或结束的位置 |
[ ^x ] | 匹配除了x以外的任意字符 |
[ ^aeiou ] | 匹配除了aeiou这几个字母以外的任意字符 |
例子:\S+
匹配不包含空白符的字符串。<a[^>]+>
匹配用尖括号括起来的以a开头的字符串
后向引用
待学习
零宽断言
待学习
负向零宽断言
待学习
注释
待学习
贪婪与懒惰
当正则表达式中包含能接受重复的限定符时,通常的行为是(在使整个表达式能得到匹配的前提下)匹配尽可能多的字符。以这个表达式为例:a.*b
,它将会匹配最长的以a
开始,以b
结束的字符串。如果用它来搜索aabab
的话,它会匹配整个字符串aabab
。这被称为贪婪匹配。
有时,我们更需要懒惰匹配,也就是匹配尽可能少的字符。前面给出的限定符都可以被转化为懒惰匹配模式,只要在它后面加上一个问号?
。这样.*?
就意味着匹配任意数量的重复,但是在能使整个匹配成功的前提下使用最少的重复。a.*?b
匹配最短的,以a
开始,以b
结束的字符串。如果把它应用于aabab
的话,它会匹配aab
(第一到第三个字符)和ab
(第四到第五个字符)
为什么第一个匹配是aab
(第一到第三个字符)而不是ab
(第二到第三个字符)?简单地说,因为正则表达式有另一条规则,比懒惰/贪婪规则的优先级更高:最先开始的匹配拥有最高的优先权
符号 | 表示 |
---|---|
*? | 重复任意次,但尽可能少重复 |
+? | 重复1次或更多次,但尽可能少重复 |
?? | 重复0次或1次,但尽可能少重复 |
{n,m}? | 重复n到m次,但尽可能少重复 |
{n,}? | 重复n次以上,但尽可能少重复 |
转载地址:https://thinkerchan.com/2016/01/05/regex/