正则小抄

397 阅读2分钟

修饰符(标记)

修饰符描述
iignore - 不区分大小写
gglobal - 全局匹配
mmulti line - 多行匹配
s特殊字符圆点 . 中包含换行符 \n

常用普通字符

字符描述
\将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符
匹配输入字符串的开始位置
$匹配输入字符串的结束位置
*匹配前面的子表达式零次或多次
+匹配前面的子表达式一次或多次
?匹配前面的子表达式零次或一次
{n}n是一个非负整数。匹配确定的n次
{n,}n是一个非负整数。至少匹配n次
{n,m}m和n均为非负整数,其中n<=m。最少匹配n次且最多匹配m次
.匹配除“\n"之外的任何单个字符
x|y匹配x或y
[xyz]字符集合。匹配所包含的任意一个字符
[^xyz]反值字符集合。匹配未包含的任意字符
[a-z]字符范围。匹配指定范围内的任意字符
[^a-z]反值字符范围。匹配任何不在指定范围内的任意字符
\b匹配一个单词边界,也就是指单词和空格间的位置
\B匹配非单词边界

常用简写

常用简写描述
\d匹配一个数字字符。等价于[0-9]
\D匹配一个非数字字符。等价于[^0-9]。
\w匹配字母、数字、下划线。等价于 [A-Za-z0-9_]
\W匹配非字母、数字、下划线。等价于 [^A-Za-z0-9_]
\s匹配任何空白字符,包括空格、制表符、换页符等等。等价于[ \f\n\r\t\v]
\S匹配任何非空白字符。等价于 [^ \f\n\r\t\v]
\n匹配一个换行符。等价于 \x0a 和 \cJ。
\r匹配一个回车符。等价于\x0d和\cM。
\n匹配一个回车符。等价于\x0d和\cM。

边界字符

常用简写描述
^匹配输入字符串的开始位置
$匹配输入字符串的结束位置
\b匹配一个单词边界 如:“ab\b"可匹配"dab"中的"ab",不能匹配"qabc"的"ab"
\B匹配非单词边界 如:“ab\B"可匹配"qabc"中的"ab",不能匹配"dab"的"ab"

先行断言和后行断言

(?=pattern) 正向先行断言

非获取匹配,正向肯定预查,在任何匹配pattern的字符串开始处匹配查找字符串,该匹配不需要获取供以后使用。例如,“Windows(?=95|98|NT|2000)”能匹配“Windows2000”中的“Windows”,但不能匹配“Windows3.1”中的“Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始

(?<=pattern) 正向后行断言

非获取匹配,反向肯定预查,与正向肯定预查类似,只是方向相反。例如,“(?<=95|98|NT|2000)Windows”能匹配“2000Windows”中的“Windows”,但不能匹配“3.1Windows”中的“Windows”。 *python的正则表达式没有完全按照正则表达式规范实现,所以一些高级特性建议使用其他语言如java、scala等

(?=pattern) 和 (?<=pattern) 正好一个取前一个取后,这样就可以取两个边界里面的值,可以很好的配合使用用,如:
匹配函数字符串的参数的正则: /(?<=().+(?=)\s+{)/
匹配函数字符串主体的的正则:/(?<={)(.|\n)+(?=})/m

(?!pattern) 负向先行断言

非获取匹配,正向否定预查,在任何不匹配pattern的字符串开始处匹配查找字符串,该匹配不需要获取供以后使用。例如“Windows(?!95|98|NT|2000)”能匹配“Windows3.1”中的“Windows”,但不能匹配“Windows2000”中的“Windows”。

列如:
匹配不含'world'的单词:\b((?!abc)\w)+\b

(?<!pattern) 负向后行断言

非获取匹配,反向否定预查,与正向否定预查类似,只是方向相反。例如“(?<!95|98|NT|2000)Windows”能匹配“3.1Windows”中的“Windows”,但不能匹配“2000Windows”中的“Windows”。 *python的正则表达式没有完全按照正则表达式规范实现,所以一些高级特性建议使用其他语言如java、scala等

列如:
匹配代码\注释:(?<!http:|\S)//.*$

贪婪与非贪婪模式

当字符紧跟在任何一个其他限制符(*,+,?,{n},{n,},{n,m})后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串

例如
字符串"aaaaaaaaaaa",/a+?/只匹配单个"a",而不是所有"a"

捕获分组与非捕获分组

捕获分组

():表示捕获分组,()会把每个分组里的匹配的值保存起来,从左向右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2,以此类推

'可以abac1111QWE'.match(/(c)(1)/) // ["c1", "c", "1", index: 5, input: "可以abac1111QWE", groups: undefined] 
				 // 这里分了两组得到 "c"和"1"

非捕获分组

非捕获分组,和捕获分组唯一的区别在于,非捕获分组匹配的值不会保存起来,如:(?:)、(?=)、 (?!)等都是非捕获,如下以(?:)为例

'可以abac1111QWE'.match(/(?:c)(1)/) // ["c1", "1", index: 5, input: "可以abac1111QWE", groups: undefined] 
				  // 这里"c"为非捕获, 所以就只有一个"1"