引言
?:exp1
表达式exp1不被认为是分组
(?=)、(?!)、(?<=)、(?<!)
体现了正则中的预查概念,其实可以理解为模拟人的思考,向后(前)多看几个字符
=
可以理解为相等
!
可以理解为不等于,也就是逻辑运算中的非
<
可以理解为方向,表示向前多看几个字符
肯定性前瞻
exp1(?=exp2)
exp1后面是exp2就匹配
否定性前瞻exp1(?!exp2)
exp1后面不是exp2就匹配
肯定性后顾(?<=exp2)exp1
exp1前面是exp2就匹配
否定性后顾(?<!exp2)exp1
exp1前面不是exp2就匹配
?:pattern
▶ 举例
● 使用 (12)(?:345)6
和 (12)(345)6
来匹配字符串 123456
● 匹配结果:2个左括号,1个分组(group)
● 匹配结果:2个左括号,2个分组(group)
▶ 结论
●这个正则表达式有2个左括号,应该有2个分组(group),但是由于 ?: 的原因,第二个分组后面的表达式不作为结果输出
?=pattern
▶ 描述
● 肯定性前瞻
● exp1(?=exp2)
exp1后面是exp2就匹配
▶ 举例
● 使用表达式a(?=b)
,只会匹配出后面是b
的a
字符
?!pattern
▶ 描述
● 否定性前瞻
● exp1(?!exp2)
exp1后面不是exp2就匹配
▶ 举例
● 使用表达式a(?!b)
,只会匹配出后面不是b
的a
字符
?<=pattern
▶ 描述
● 肯定性后顾
● (?<=exp2)exp1
exp1前面是exp2就匹配
▶ 举例
● 使用表达式(?<=b)a
,只会匹配出前面是b
的a
字符
?<!pattern
▶ 描述
● 否定性后顾
● (?<!exp2)exp1
exp1前面不是exp2就匹配
▶ 举例
● 使用表达式(?<!b)a
,只会匹配出前面不是b
的a
字符
以下解释来自于官方说明:
(?:pattern)
非获取匹配,匹配pattern但不获取匹配结果,不进行存储供以后使用。这在使用或字符“(|)”来组合一个模式的各个部分时很有用。例如“industr(?:y|ies)”就是一个比“industry|industries”更简略的表达式。
(?=pattern)
非获取匹配,正向肯定预查,在任何匹配pattern的字符串开始处匹配查找字符串,该匹配不需要获取供以后使用。例如,“Windows(?=95|98|NT|2000)”能匹配“Windows2000”中的“Windows”,但不能匹配“Windows3.1”中的“Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。
(?!pattern)
非获取匹配,正向否定预查,在任何不匹配pattern的字符串开始处匹配查找字符串,该匹配不需要获取供以后使用。例如“Windows(?!95|98|NT|2000)”能匹配“Windows3.1”中的“Windows”,但不能匹配“Windows2000”中的“Windows”。
(?<=pattern)
非获取匹配,反向肯定预查,与正向肯定预查类似,只是方向相反。例如,“(?<=95|98|NT|2000)Windows”能匹配“2000Windows”中的“Windows”,但不能匹配“3.1Windows”中的“Windows”。
*python的正则表达式没有完全按照正则表达式规范实现,所以一些高级特性建议使用其他语言如java、scala等
(?<!pattern)
非获取匹配,反向否定预查,与正向否定预查类似,只是方向相反。例如“(?<!95|98|NT|2000)Windows”能匹配“3.1Windows”中的“Windows”,但不能匹配“2000Windows”中的“Windows”。
*python的正则表达式没有完全按照正则表达式规范实现,所以一些高级特性建议使用其他语言如java、scala等