1 入门:元字符
表示 | 解释 |
---|---|
1.. | 匹配除换行符以外的任意字符 |
2.\b元字符 | 代表单词的开头或结尾 |
3.\d元字符 | 代表任意数字 |
4.\w元字符 | 匹配字母、数字、下划线、汉字 |
6.^元字符 | 匹配字符串开始 |
7.$元字符 | 匹配字符串结束 |
8.{5,12}限制条件 | 重复5到12次 |
9.\ ,转义字符 | 用来使用元字符本身 |
10.[aeiou] | 自定义元字符 |
举例:
1.查找hi后面不远处跟着一个Lucy \bhi\b.*\bLucy\b
2.精确查找’hi’ \bhi\b
3.搜索国内固定电话 0\d\d-\d\d\d\d\d\d\d\d
8.QQ只能输入5-12位数字 ^\d{5-12}$ 或者\b\d{5,12}\d
10.[aeiou]匹配所有元音字母,[0-9]==\d,[a-z0-9A-Z]==\w(只考虑英文)
入门:限定符(限定前面的内容)
限定符 | 意义 |
---|---|
* | 重复零次或更多次 |
+ | 重复一次或更多次 |
? | 重复零次或一次 |
{n} | 重复n次 |
{n,} | 重复n此或更多 |
{n,m} | 重复n到m次 |
- 例子1:
Windows\d+
匹配windows后跟1个或多个数字^\w+
匹配字符串中的第一个词
\(?0\d{2}[) -]?\d{8}
理解:(?表示匹配0或1此( 0表示匹配0 \d{2}表示两个数字 [)
-]?表示)空格-
中匹配到任意一个或者不匹配 \d{8} 表示8个数字
–>这样做的结果:好的 (010)88886666,或022-22334455,或02912345678
不好的 010)12345678或(022-87654321
分枝条件|
和or类似,符合条件的都列出来,相比于单一限定条件,这样反而精确了,
例子1: 0\d{2}-\d{8}|0\d{3}-\d{7} 012-12345678 相比于\(?0\d{2}[) -]?\d{8}
,排除了上面几个不好的结果
例子2:\(0\d{2}\)[- ]?\d{8}|0\d{2}[- ]?\d{8}
匹配到:(012)-12345678|012-12345678
***例子3:\d{5}-\d{4}|\d{5}
效果:12345-1234 匹配到12345
\d{5}-\d{5}-\d{4}
匹配12345-6789会是什么结果?12345
例子4:\d{5}-\d{4}|\d{5}
匹配12345-6789结果?12345-6789
说明用|执行相互包含的条件时要把复杂条件写在前面,否则先匹配到简单的条件指针也不会自己再回头了,复杂的条件就匹配不到了
分组:()
小括号来指定表达式,类似于运算符中的效果,可以给限定条件指定前面的作用范围—
例3((2[0-4]\d|25[0-5]|[01]?\d\d?).){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)
分析:2[0-4]\d表示2+[1,2,3,4]+num 25[0-5]表示25+[0-5]两个是或的关系
[01]?\d\d?表示0或1取一位或不取+数字+数字取一位或不取 .表示接了一个. {3}表示前面括号中的内容重复三次后面括号里的内容和前面一样,只是ip地址中最后没有.了 所以这是匹配ip地址的正则表达式
反义:
符号 | 意义 |
---|---|
\W | 匹配非字母、数字、下划线、汉字的字符 |
\S | 匹配非空白符的字符 |
\D | 匹配非数字 |
\B | 匹配非单词开头或结尾的位置 |
[^x] | 匹配除了x以外的任意字符 |
[^aeiou] | 匹配除了元音以外的任意字符 |
\S+匹配不含空白符的字符串
<a[^>]+> 匹配尖括号括住的以a开头后面不是紧跟着>的字符串**
- 举例:
<a[^>]+>
去匹配和ojvqo qwf> 的结果为和
后向引用:
子表达式的组号–(为标志(组2(组3(组4
- 举例:
\b(\w+)\b\s+\1\b
理解:\b(\w+)\b表示一个单词
\s+表示一个或多个空白格
**\1\b表示选定前面的第一个括号内容为条件进行限定,限定的内容是这个单词作为末尾
:也可以自定义组号:(?<Word>\w+)
把W+的组名指定成word,\k可以反向引用分组捕获的内容
举例2 **\b(\w+)\b\s+\1\b
也可以写成\b(?\w+)\b\s+\k\b
总结()小括号的用法:
(aaa) | 匹配aaa并放入\1组中 |
---|---|
(?aaa) | 匹配aaa放入name组中,或(?'name’exp)—'是单引号不是反引号 |
(?:aaa) | 匹配aaa,不捕获文本,也不分配组号 |
(?=aaa) | 匹配aaa,前面的位置 |
(?<=aaa) | 匹配aaa后面的位置 |
(?!aaa) | 匹配非aaa的位置 |
(?<!aaa) | 匹配前面不是aaa的位置 |
(?#comment) | 无效果,相当于#注释 |
断言—断言为真时才匹配
零宽断言:
(?=exp)也叫零宽度正预测先行断言 ,匹配以ing结尾的单词的前面部分
- 举例:对12345-6789使用\b\w+(?=345)=12
(?<=exp)也叫零宽度正回顾后发断言,匹配以re开头的单词的后半部分
-
举例:对12345-6789使用(?<=\b123)\w+\b=45
**?假如你想要给一个很长的数字中每三位间加一个逗号(当然是从右边加起了),你可以这样查找需要在前面和里面添加逗号的部分:((?<=\d)\d{3})+\b,用它对1234567890进行查找时结果是234567890。
(?<=\s)\d+(?=\s)表示匹配两个空白格之间的字符串 (?<=\s)表示匹配空白后面,(?=\s)表示匹配空白前面
负向零宽断言:
前面的例子出现的问题:\b\w*q[^u]\w*\b
匹配包含后面不是字母u的字母q的单词(加入q在单词最后就会报错)
解决办法:\b\w*q(?!u)\w*\b
负向零宽断言
一.(?!aaa)形式,用于表示后面不再匹配的表达式aaa–>
- 举例:
\d{3}(?!\d)
匹配三位数字,而且这三位数字的后面不能是数字
二.(?<!exp)
断言此位置的前面不能匹配表达式exp
-
举例1:
(?<![a-z])\d{7}
匹配前面不是小写字母的七位数字 -
***举例2:
(?<=<(\w+)>).*(?=<\/\1>)
分析:(?<=<(\w+)>)代表\w+内容的前缀; .*代表任意内容; (?=</\1>)代表/+\w+的后缀; 所以连起来就是:这里就是要匹配的内容
注释:***(?#comment)
- 举例1:
2[0-4]\d(?#200-249)|25[0-5](?#250-255)|[01]?\d\d?(?#0-199)
分析:215(#200-249)| 255(#250-255)| 1(#0-199)
***启用“忽略模式里的空白符”选项后,
`(?<= | # 断言要匹配的文本的前缀 |
---|---|
<(\w+)> | ` # 查找尖括号括起来的字母或数字(即HTML/XML标签) |
) | # 前缀结束 |
– | – |
* | # 匹配任意文本 |
(?= | # 断言要匹配的文本的后缀 |
</\1> | # 查找尖括号括起来的内容:前面是一个"/",后面是先前捕获的标签 |
) | # 后缀结束 |
贪婪与懒惰模式
>a.*b:效果aabab-->a.*b-->aabab
贪婪模式尽量多
a.*?b:效果aabab-->a.*?b-->aabab
懒惰模式尽量少
- *? 重复任意次,但尽可能少重复
- +? 重复1次或更多次,但尽可能少重复
- ?? 重复0次或1次,但尽可能少重复
- {n,m}? 重复n到m次,但尽可能少重复
- {n,}? 重复n次以上,但尽可能少重复
处理选项
-
IgnoreCase(忽略大小写)
-
Multiline(多行模式)
-
Singleline(单行模式)
-
IgnorePatternWhitespace(忽略空白)
-
ExplicitCapture(显式捕获)
注意:单行模式或多行模式没有任何关系,可以同时使用
递归匹配
xx <aa aa> yy中尖括号中的内容匹配出来
套路:
(?'group')
把捕获的内容命名为group,并压入堆栈(Stack)
(?'-group')
从堆栈上弹出最后压入堆栈的名为group的捕获内容,如果堆栈本来为空,则本分组的匹配失败
(?(group)yes|no)
如果堆栈上存在以名为group的捕获内容的话,继续匹配yes部分的表达式,否则继续匹配no部分
(?!)
零宽负向先行断言,由于没有后缀表达式,试图匹配总是失败
思路:xx <aa aa> yy
< #最外层的左括号
[^<>]* #最外层的左括号后面的不是括号的内容
(
(
(?'Open'<) #碰到了左括号,在黑板上写一个"Open"
[^<>]* #匹配左括号后面的不是括号的内容
)+
(
(?'-Open'>) #碰到了右括号,擦掉一个"Open"
[^<>]* #匹配右括号后面不是括号的内容
)+
)*
(?(Open)(?!)) #在遇到最外层的右括号前面,判断黑板上还有没有没擦掉的"Open";如果还有,则匹配失败
> #最外层的右括号
****匹配嵌套的<div>标签:<div[^>]*>[^<>]*(((?'Open'<div[^>]*>)[^<>]*)+((?'-Open'</div>)[^<>]*)+)*(?(Open)(?!))</div>.
其他:
- \t 制表符,Tab
- \r 回车
- \v 竖向制表符
- \f 换页符
- \n 换行符
- \A 字符串开头(类似^,但不受处理多行选项的影响)
- \Z 字符串结尾或行尾(不受处理多行选项的影响)
- \z 字符串结尾(类似$,但不受处理多行选项的影响)
- (?-exp) 平衡组
- (?im-nsx:exp) 在子表达式exp中改变处理选项
- (?im-nsx) 为表达式后面的部分改变处理选项
- (?(exp)yes|no) 把exp当作零宽正向先行断言,如果在这个位置能匹配,使用yes作为此组的表达式;否则使用no
- (?(exp)yes) 同上,只是使用空表达式作为no
- (?(name)yes|no) 如果命名为name的组捕获到了内容,使用yes作为表达式;否则使用no
- (?(name)yes) 同上,只是使用空表达式作为no
这只是我的学习笔记,原文在下面的链接,工具也是原文中的,讲解的特别好,让我终于入门了正则,在此表示感谢!