正则表达式基础


re中文文档
re官方文档
正则表达式在线测试
hackerrank在线练习

基本语法

基本语法_菜鸟教程
\表示特殊形式或允许使用特殊字符,而不调用其特殊含义
不以任何特殊方式在字符串字面值中以'r'前缀处理反斜杠
所以r'\n'包含'\''n'两个字符,而'\n'表示换行符
'.'默认情况下,匹配除换行符之外的任何字符,如果DOTALL标志被指定时,则匹配任何字符
'^'匹配开始位置
'$'匹配结束位置
'*'前面重复出现的正则表达式零次或多次,尽可能多地匹配
'+'一次或多次,尽可能多
'?'零次或1次
'*?','+?','??'匹配尽可能少(不存在则为0次,存在则为1次)
{m} 精确指定匹配m次,少于m次则不会被匹配
{m,n}m~n个重复,尽可能多的重复
{m,n}? m~n个重复,尽可能少
'\' 消除特殊字符含义或特殊序列
[] 用来表示一个字符集和,字符可以被单独罗列
[0-9a-z]范围内的任意字符
[a-]将匹配字符'-'
[(+*?)]集合内的特殊字符失去特殊意义,将匹配(,),+,*,?
[^5]除5外的任意字符,当^不再集合的第一个位置时将没有特殊意义
想要在一个集合内匹配],需要在它的前面使用一个反斜杠转义(或者在集合开头处将它替换)
'|' A|B满足A或B,从左向右运算,不贪婪,即一旦A匹配则忽略B的测试
\d数字
\D非数字
\s空白字符
\w包含下划线在内的单词字符[A-Za-z0-9_]
(?=exp)匹配exp前面的位置
(?<=exp)匹配exp后面的位置

回溯陷阱

参考:

一个由正则表达式引发的血案_博客园
藏在正则表达式中的陷阱_掘金

正则表达式引擎

DFA(Deterministic Final Automata,确定型有穷自动机)与NFA(Non deterministic Finite Automaton,不确定型有穷自动机)

DFA从匹配文本入手,从左至右,每个字符不会匹配两次,时间复杂度是多项式的,速度快、支持特性少,不支持捕获组、引用等。

NFA从正则表达式入手,不断读入字符,尝试是否匹配当前正则,不匹配则弹出字符重新尝试,速度慢,最优时间复杂度式多项式,最差情况为指数级

Java、.NET、Perl、Python、Ruby、PhP、JS都是由NFA实现

text = 'after tonight'
regex = 'to(nite|nighta|night)'

在NFA匹配时候,是根据正则表达式来匹配文本的,从t开始匹配a,失败,继续,直到文本里面的第一个t,接着比较o和e,失败,正则回退到 t,继续,直到文本里面的第二个t,然后 o和文本里面的o也匹配,继续,正则表达式后面有三个可选条件,依次匹配,第一个失败,接着二、三,直到匹配。
而在DFA匹配时候,采用的是用文本来匹配正则表达式的方式,从a开始匹配t,直到第一个t跟正则的t匹配,但e跟o匹配失败,继续,直到文本里面的第二个 t 匹配正则的t,接着o与o匹配,n的时候发现正则里面有三个可选匹配,开始并行匹配,直到文本中的g使得第一个可选条件不匹配,继续,直到最后匹配。
可以看到,DFA匹配过程中文本中的字符每一个只比较了一次,没有吐出的操作,应该是快于NFA的。另外,不管正则表达式怎么写,对于DFA而言,文本的匹配过程是一致的,都是对文本的字符依次从左到右进行匹配,所以,DFA在匹配过程中是跟正则表达式无关的,而 NFA 对于不同但效果相同的正则表达式,匹配过程是完全不同的。

回溯

ab{1,3}c

也就是说中间的b需要匹配1~3次。那么对于文本abbbc,按照第1部分NFA引擎的匹配规则,其实是没有发生回溯的,在表达式中的a匹配完成之后,b恰好和文本中的3个b完整匹配,之后是c发生匹配,一气呵成。如果我们把文本换成abc呢?无非就是少了一个字母b,却发生了所谓的回溯。

贪婪、懒惰、独占

  • ?:匹配字符0次或1次
  • +:匹配字符1次或多次
  • *:匹配字符0次或多次
  • {min,max}:匹配minmax

贪婪模式:默认均为贪婪模式,匹配尽可能多的内容
懒惰模式:在以上字符后加上一个?,匹配尽可能少的重复字符
独占模式:匹配最长,但不发生回溯,一但匹配不成功就结束匹配

ab{1,3}+bc

上述表达式即为独占模式,该表达式不会匹配任何文本

python re模块

re.compile(pattern,flags=0)

将正则表达式编译成一个正则表达式对象,可以调用match() search()方法

prog=re.compile(pattern)
result=prog.match(string)

re.DEBUG

显示调试信息编译的表达式

re.IGNORECASE(re.I)

执行忽略大小写的匹配

re.MULTILINE(re.M)

指定时,模式字符'^'在字符串开头和每行开头匹配,紧挨每个换行符后;
模式字符'$'在字符串的末尾和每行的末尾,紧挨每个换行符之前;
默认'^'字符串开头,'$'字符串结尾

re.DOTALL(re.S)

'.'特殊字符匹配任何字符,包括换行符;没有则匹配除换行符之外的任何字符

re.VERBOSE(re.X)

re.search(pattern,string,flags=0)

扫描字符串查找匹配的第一个位置,并返回相应的match object。否则返回None

re.match(pattern,string, flags=0)

从开始位置进行匹配

re.fullmatch(pattern,string,flags=0)

必须要整个字符串与之匹配。

re.findall(pattern,string,flags=0)

从左向右扫描

正则表达式对象

regex.search(string[,pos[,endpos]])

返回第一个
pos:搜索开始处
endpos:结束处

regex.match(string[,pos[,endpos]])

从该字符串开始处匹配

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值