前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >正则表达式基础

正则表达式基础

作者头像
JNJYan
发布2019-01-18 09:54:16
6950
发布2019-01-18 09:54:16
举报

基本语法

基本语法_菜鸟教程\表示特殊形式或允许使用特殊字符,而不调用其特殊含义 不以任何特殊方式在字符串字面值中以'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实现

代码语言:javascript
复制
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 对于不同但效果相同的正则表达式,匹配过程是完全不同的。

回溯

代码语言:javascript
复制
ab{1,3}c

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

贪婪、懒惰、独占

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

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

代码语言:javascript
复制
ab{1,3}+bc

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

python re模块

代码语言:javascript
复制
re.compile(pattern,flags=0)

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

代码语言:javascript
复制
prog=re.compile(pattern)
result=prog.match(string)

代码语言:javascript
复制
re.DEBUG

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

代码语言:javascript
复制
re.IGNORECASE(re.I)

执行忽略大小写的匹配

代码语言:javascript
复制
re.MULTILINE(re.M)

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

代码语言:javascript
复制
re.DOTALL(re.S)

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

代码语言:javascript
复制
re.VERBOSE(re.X)

代码语言:javascript
复制
re.search(pattern,string,flags=0)

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

代码语言:javascript
复制
re.match(pattern,string, flags=0)

从开始位置进行匹配

代码语言:javascript
复制
re.fullmatch(pattern,string,flags=0)

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

代码语言:javascript
复制
re.findall(pattern,string,flags=0)

从左向右扫描

正则表达式对象

代码语言:javascript
复制
regex.search(string[,pos[,endpos]])

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

代码语言:javascript
复制
regex.match(string[,pos[,endpos]])

从该字符串开始处匹配

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018年11月20日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 基本语法
  • 回溯陷阱
    • 正则表达式引擎
      • 回溯
        • 贪婪、懒惰、独占
        • python re模块
          • 正则表达式对象
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档