正则表达式
\b 是特殊代码,元字符 metacharacter,代表单词的开头或结尾,即为单词的分界处,英文单词由空格、标点符号或者换行来分隔,但是\b不匹配单词的分割字符的任何一个,只匹配一个位置。
\bhi\b.*\bLucy\b 同一行中有hi和Lucy单词的一行,但是hi和Lucy不能在不同行。
0\d\d-\d\d\d\d\d\d\d\d匹配以0开头,然后两个数字,连字号-,后面有8个数字。
0\d\d-\d\d\d\d\d\d\d\d 等价于 0\d{2}-\d{8} ,{n}表示前一个元字符重复n次。
\s 匹配任意的空白符,包括空格、制表符(tab)、换行符、中文全角空格等。
\w 匹配字母或数字或下划线或汉字等
\ba\w\b 匹配以字母a开头的单词--单词字母a,然后是任意数量的字母或数字(\w),最后是单词的结束(\b)。
+ 匹配重复1次或更多次,* 匹配重复任意次(0次,1次和多次)
\b\w{6}\b 匹配6个字符的单词
代码 | 说明 | |||
. | 匹配除换行符以外的任意字符 | |||
\w | 匹配字母或数字或下划线或汉字 | |||
\s | 匹配任意的空白符 | |||
\d | 匹配数字 | |||
\b | 匹配单词的开始或结束的位置 | |||
^ | 匹配字符串的开始 | |||
$ | 匹配字符串的结束 |
字符转义: . * \ 匹配. * \
代码 | 说明 | |||
* | 重复零次或更多次 | |||
+ | 重复一次或更多次 | |||
? | 重复零次或一次 | |||
{n} | 重复n次 | |||
{n,} | 重复n次或更多次 | |||
{n,m} | 重复n到m次 |
^\w+ 匹配一行的第一个单词
“(?0\d{2}[) -]?\d{8}” 匹配:(010)88886666,或022-22334455,或02912345678 010)12345678或(022-87654321等
(\d{1,3}.){3}\d{1,3} 匹配IP地址 ,合理的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之外的任意字符 |
后向引用
用于重复搜索前面某个分组匹配的文本。
\b(\w+)\b\s+\1\b 用来匹配重复的单词,如go go和kity kity (\b(\w+)\b) 匹配一个单词,一个或几个空白符(\s+), \1 代表分组1匹配点文本。
子表达式的组名:(?
分组语法如下:
分类 | 代码/语法 | 说明 | ||||
捕获 | (exp) | 匹配exp,并捕获文本到自动命名的组里 | ||||
(? |
捕获文档到命名为name的组里,也可以(?‘name’exp) | |||||
(?:exp) | 不捕获匹配的文本,也不给此分组分配组号 | |||||
零宽断言 | (?=exp) | 匹配exp前面的位置 | ||||
(?<= exp) | 匹配exp后面的位置 | |||||
(?!exp) | 匹配后面跟的不是exp的位置 | |||||
(?<!exp) | 匹配前面不是exp的位置 | |||||
注释 | (?#comment) | 这种类型的分组不对正则表达式的处理产生任何影响,用于提供注释让人阅读 |
零宽断言:
\b ^ $ 用于指定一个位置,被称为零宽断言。
(?=exp),断言自身出现的位置的后面能匹配表达式exp。 \b\w+(?=ing\b),匹配ing为结尾的单词的前面部分。I’m singing while you’re dancing。匹配到的事sing和danc。
(?<=exp)断言自身出现的位置的前面能匹配表达式exp。(?<=\bre)\w+\b ,匹配以re开头对单词的后半部分。reading匹配到的ading。
((?<=\d)\d{3})+\b ,用它对1234567890查找时,结果为234567890. (?<=\s)\d+(?=\s)匹配以空白符间隔的数字(再次强调,不包括这些空白符)
负向零宽断言: 确保某个字符没有出现,但并不想去匹配它。 想匹配单词,它出现q,但是q后面跟的不是u: \b\wq[^u]\w\b匹配包含包含字母q且q后面不是u的单词。但是Iraq和Benq,匹配不到。 \b\wq(?!u)\w\b 匹配包含q,且q后面不是u的单词,且可以匹配Iraq和Benq。
零宽度负预测先行断言(?!exp),断言此位置的后面不能匹配表达式exp。例如:\d{3}(?!\d)匹配三位数字,而且这三位数字的后面不能是数字;\b((?!abc)\w)+\b匹配不包含连续字符串abc的单词。
可以用(?<!exp),零宽度负回顾后发断言来断言此位置的前面不能匹配表达式exp:(?<![a-z])\d{7}匹配前面不是小写字母的七位数字。
(?<=<(\w+)>).*(?=<\/\1>)匹配不包含属性的简单HTML标签内里的内容。
贪婪与懒惰
匹配尽可能多的字符。a.b,匹配aabab时,会匹配aabab,称为贪婪匹配。 相反,匹配尽可能少的字符。 .?意味任意数量的重复,但是在能使整个匹配成功的前提下使用最少的重复。a.*?b匹配最短的,以a开始,以b结束的字符串。如果把它应用于aabab的话,它会匹配aab(第一到第三个字符)和ab(第四到第五个字符)
懒惰限定符:
代码/语法 | 说明 | |||
*? | 重复任意次,但尽可能少重复 | |||
+? | 重复1次或更多次,但尽可能少重复 | |||
?? | 重复0或1次,但尽可能少重复 | |||
{n,m}? | 重复n到m次,但尽可能少重复 | |||
{n,}? | 重复n次以上,但尽可能少重复 |
平衡组/递归匹配
匹配像( 100 * ( 50 + 15 ) )嵌套层次性解构,
这里需要用到以下的语法构造:
- (?’group’) 把捕获的内容命名为group,并压入堆栈(Stack)
- (?’-group’) 从堆栈上弹出最后压入堆栈的名为group的捕获内容,如果堆栈本来为空,则本分组的匹配失败
-
(?(group)yes no) 如果堆栈上存在以名为group的捕获内容的话,继续匹配yes部分的表达式,否则继续匹配no部分 - (?!) 零宽负向先行断言,由于没有后缀表达式,试图匹配总是失败
碰到左括号压入,碰到有括号,弹出,最后看堆栈是否为空-不为空则匹配失败。
< #最外层的左括号 [^<>]* #最外层的左括号后面的不是括号内容 ( ( (?‘Open’<) #碰到左括号,黑板写一个Open [^<>]* #匹配左括号后面的不是括号的内容 )+ ( (?‘-Open’>) #碰到右括号,擦掉一个Open [^<>]* #匹配右括号后面不是括号的内容 )+ )* (?(Open)(?!))
# 再遇到最外层的右括号前面,判断黑板上是否还有open,如果还有则匹配失败。
平衡组的一个最常见的应用就是匹配HTML,下面的例子可以匹配嵌套<div>标签: <div[^>]>[^<>](((?’Open’<div[^>]>)[^<>])+((?’-Open’</div>)[^<>])+)(?(Open)(?!))</div>.
代码/语法 | 说明 | |||
\a | 报警字符(打印它的效果是电脑嘀一声) | |||
\b | 通常是单词分界位置,但如果在字符类里使用代表退格 | |||
\t | 制表符,Tab | |||
\r | 回车 | |||
\v | 竖向制表符 | |||
\f | 换页符 | |||
\n | 换行符 | |||
\e | Escape | |||
\0nn | ASCII代码中八进制代码为nn的字符 | |||
\xnn | ASCII代码中十六进制代码为nn的字符 | |||
\unnnn | Unicode代码中十六进制代码为nnnn的字符 | |||
\cN | ASCII控制字符。比如\cC代表Ctrl+C | |||
\A | 字符串开头(类似^,但不受处理多行选项的影响) | |||
\Z | 字符串结尾或行尾(不受处理多行选项的影响) | |||
\z | 字符串结尾(类似$,但不受处理多行选项的影响) | |||
\G | 当前搜索的开头 | |||
\p{name} | Unicode中命名为name的字符类,例如\p{IsGreek} | |||
(?>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 |