2.2 反向引用 \1, \2...

表达式在匹配时,表达式引擎会将小括号 "( )" 包含的表达式所匹配到的字符串记录下来。在获取匹配结果的时候,小括号包含的表达式所匹配到的字符串可以单独获取。这一点,在前面的举例中,已经多次展示了。在实际应用场合中,当用某种边界来查找,而所要获取的内容又不包含边界时,必须使用小括号来指定所要的范围。比如前面的 "<td>(.*?)</td>"。

其实,"小括号包含的表达式所匹配到的字符串" 不仅是在匹配结束后才可以使用,在匹配过程中也可以使用。表达式后边的部分,可以引用前面 "括号内的子匹配已经匹配到的字符串"。引用方法是 "\" 加上一个数字。"\1" 引用第1对括号内匹配到的字符串,"\2" 引用第2对括号内匹配到的字符串……以此类推,如果一对括号内包含另一对括号,则外层的括号先排序号。换句话说,哪一对的左括号 "(" 在前,那这一对就先排序号。

举例如下:

举例1:表达式 "('|")(.*?)(\1)" 在匹配 " 'Hello', "World" " 时,匹配结果是:成功;匹配到的内容是:" 'Hello' "。再次匹配下一个时,可以匹配到 " "World" "。

举例2:表达式 "(\w)\1{4,}" 在匹配 "aa bbbb abcdefg ccccc 111121111 999999999" 时,匹配结果是:成功;匹配到的内容是 "ccccc"。再次匹配下一个时,将得到 999999999。这个表达式要求 "\w" 范围的字符至少重复5次,

注意与 "\w{5,}" 之间的区别。

举例3:表达式 "<(\w+)\s*(\w+(=('|").*?\4)?\s*)*>.*?</\1>" 在匹配 "<td id='td1' style="bgcolor:white"></td>" 时,匹配结果是成功。如果 "<td>" 与 "</td>" 不配对,则会匹配失败;如果改成其他配对,也可以匹配成功。

2.3 预搜索,不匹配;反向预搜索,不匹配

前面的章节中,我讲到了几个代表抽象意义的特殊符号:"^","$","\b"。它们都有一个共同点,那就是:它们本身不匹配任何字符,只是对 "字符串的两头" 或者 "字符之间的缝隙" 附加了一个条件。理解到这个概念以后,本节将继续介绍另外一种对 "两头" 或者 "缝隙" 附加条件的,更加灵活的表示方法。

正向预搜索:"(?=xxxxx)","(?!xxxxx)"

格式:"(?=xxxxx)",在被匹配的字符串中,它对所处的 "缝隙" 或者 "两头" 附加的条件是:所在缝隙的右侧,必须能够匹配上 xxxxx 这部分的表达式。因为它只是在此作为这个缝隙上附加的条件,所以它并不影响后边的表达式去真正匹配这个缝隙之后的字符。这就类似 "\b",本身不匹配任何字符。"\b" 只是将所在缝隙之前、之后的字符取来进行了一下判断,不会影响后边的表达式来真正的匹配。

举例1:表达式 "Windows (?=NT|XP)" 在匹配 "Windows 98, Windows NT, Windows 2000" 时,将只匹配 "Windows NT" 中的 "Windows ",其他的 "Windows " 字样则不被匹配。

举例2:表达式 "(\w)((?=\1\1\1)(\1))+" 在匹配字符串 "aaa ffffff 999999999" 时,将可以匹配6个"f"的前4个,可以匹配9个"9"的前7个。这个表达式可以读解成:重复4次以上的字母数字,则匹配其剩下最后2位之前的部分。当然,这个表达式可以不这样写,在此的目的是作为演示之用。

格式:"(?!xxxxx)",所在缝隙的右侧,必须不能匹配 xxxxx 这部分表达式。

举例3:表达式 "((?!\bstop\b).)+" 在匹配 "fdjka ljfdl stop fjdsla fdj" 时,将从头一直匹配到 "stop" 之前的位置,如果字符串中没有 "stop",则匹配整个字符串。

举例4:表达式 "do(?!\w)" 在匹配字符串 "done, do, dog" 时,只能匹配 "do"。在本条举例中,"do" 后边使用 "(?!\w)" 和使用 "\b" 效果是一样的。

反向预搜索:"(?<=xxxxx)","(?<!xxxxx)"

<p class="title" title="淘金币 赛格兰SGL-1501电热水壶特价包邮 烧水壶正品 不锈钢电水"> 淘金币 赛格兰SGL-1501电热水壶特价包邮 烧水壶正品 不锈钢电水 </p>

<p class="price"><del>[/color]108.00</del><span class="discount">/3.7折</span> <span class="salescount">已成交53件</span> </p>

<p class="price qz-price"> <em>39.96</em>+150<span class="coin">淘金币</span> <span class="favorable">  运费0.03 </span>  </p>

(?<=title=\"淘金币).+?(?=<del>)

这两种格式的概念和正向预搜索是类似的,反向预搜索要求的条件是:所在缝隙的 "左侧",两种格式分别要求必须能够匹配和必须不能够匹配指定表达式,而不是去判断右侧。与 "正向预搜索" 一样的是:它们都是对所在缝隙的一种附加条件,本身都不匹配任何字符。

举例5:表达式 "(?<=\d{4})\d+(?=\d{4})" 在匹配 "1234567890123456" 时,将匹配除了前4个数字和后4个数字之外的中间8个数字。

3. 其他通用规则

还有一些在各个正则表达式引擎之间比较通用的规则,在前面的讲解过程中没有提到。

3.1 表达式中,可以使用 "\xXX" 和 "\uXXXX" 表示一个字符("X" 表示一个十六进制数)

形式

字符范围

\xXX

编号在 0 ~ 255 范围的字符,比如:

空格可以使用 "\x20" 表示

\uXXXX

任何字符可以使用 "\u" 再加上其编号的4位十六进制数表示,比如:

"\u4E2D"

3.2 在表达式 "\s","\d","\w","\b" 表示特殊意义的同时,对应的大写字母表示相反的意义

表达式

可匹配

\S

匹配所有非空白字符("\s" 可匹配各个空白字符)

\D

匹配所有的非数字字符

\W

匹配所有的字母、数字、下划线以外的字符

\B

匹配非单词边界,即左右两边都是 "\w" 范围或者左右两边都不是 "\w" 范围时的字符缝隙

3.3 在表达式中有特殊意义,需要添加 "\" 才能匹配该字符本身的字符汇总

字符

说明

^

匹配输入字符串的开始位置。要匹配 "^" 字符本身,请使用 "\^"

$

匹配输入字符串的结尾位置。要匹配 "$" 字符本身,请使用 "\$"

( )

标记一个子表达式的开始和结束位置。要匹配小括号,请使用 "\(" 和 "\)"

[ ]

用来自定义能够匹配 '多种字符' 的表达式。要匹配中括号,请使用 "\[" 和 "\]"

{ }

修饰匹配次数的符号。要匹配大括号,请使用 "\{" 和 "\}"

.

匹配除了换行符(\n)以外的任意一个字符。要匹配小数点本身,请使用 "\."

?

修饰匹配次数为 0 次或 1 次。要匹配 "?" 字符本身,请使用 "\?"

+

修饰匹配次数为至少 1 次。要匹配 "+" 字符本身,请使用 "\+"

*

修饰匹配次数为 0 次或任意次。要匹配 "*" 字符本身,请使用 "\*"

|

左右两边表达式之间 "或" 关系。匹配 "|" 本身,请使用 "\|"

3.4 括号 "( )" 内的子表达式,如果希望匹配结果不进行记录供以后使用,可以使用 "(?:xxxxx)" 格式

举例1:表达式 "(?:(\w)\1)+" 匹配 "a bbccdd efg" 时,结果是 "bbccdd"。括号 "(?:)" 范围的匹配结果不进行记录,因此 "(\w)" 使用 "\1" 来引用。

3.5 常用的表达式属性设置简介:Ignorecase,Singleline,Multiline,Global

表达式属性

说明

Ignorecase

默认情况下,表达式中的字母是要区分大小写的。配置为 Ignorecase 可使匹配时不区分大小写。有的表达式引擎,把 "大小写" 概念延伸至 UNICODE 范围的大小写。

Singleline

默认情况下,小数点 "." 匹配除了换行符(\n)以外的字符。配置为 Singleline 可使小数点可匹配包括换行符在内的所有字符。

Multiline

默认情况下,表达式 "^" 和 "$" 只匹配字符串的开始 ① 和结尾 ④ 位置。如:

①xxxxxxxxx②\n

③xxxxxxxxx④

配置为 Multiline 可以使 "^" 匹配 ① 外,还可以匹配换行符之后,下一行开始前 ③ 的位置,使 "$" 匹配 ④ 外,还可以匹配换行符之前,一行结束 ② 的位置。

Global

主要在将表达式用来替换时起作用,配置为 Global 表示替换所有的匹配。

4. 其他提示

4.2 如果要要求表达式所匹配的内容是整个字符串,而不是从字符串中找一部分,那么可以在表达式的首尾使用 "^" 和 "$",比如:"^\d+$" 要求整个字符串只有数字。

4.3 如果要求匹配的内容是一个完整的单词,而不会是单词的一部分,那么在表达式首尾使用 "\b",比如:

使用 "\b(if|while|else|void|int……)\b" 来匹配程序中的关键字。

4.4 表达式不要匹配空字符串。否则会一直得到匹配成功,而结果什么都没有匹配到。比如:准备写一个匹配 "123"、"123."、"123.5"、".5" 这几种形式的表达式时,整数、小数点、小数数字都可以省略,但是不要将表达式写成:"\d*\.?\d*",因为如果什么都没有,这个表达式也可以匹配成功。

更好的写法是:"\d+\.?\d*|\.\d+"。

4.5 能匹配空字符串的子匹配不要循环无限次。如果括号内的子表达式中的每一部分都可以匹配 0 次,而这个括号整体又可以匹配无限次,那么情况可能比上一条所说的更严重,匹配过程中可能死循环。虽然现在有些正则表达式引擎已经通过办法避免了这种情况出现死循环了,比如 .NET 的正则表达式,但是我们仍然应该尽量避免出现这种情况。如果我们在写表达式时遇到了死循环,也可以从这一点入手,查找一下是否是本条所说的原因。

4.7 或 "|" 的左右两边,对某个字符最好只有一边可以匹配,这样,不会因为 "|" 两边的表达式因为交换位置而有所不同。

转载于:https://www.cnblogs.com/likeshu/p/4967386.html

python中关于正则表达式二相关推荐

  1. [Python]网络爬虫(七):Python中的正则表达式教程(转)

    接下来准备用糗百做一个爬虫的小例子. 但是在这之前,先详细的整理一下Python中的正则表达式的相关内容. 正则表达式在Python爬虫中的作用就像是老师点名时用的花名册一样,是必不可少的神兵利器. ...

  2. [Python]网络爬虫(七):Python中的正则表达式教程

    接下来准备用糗百做一个爬虫的小例子. 但是在这之前,先详细的整理一下Python中的正则表达式的相关内容. 正则表达式在Python爬虫中的作用就像是老师点名时用的花名册一样,是必不可少的神兵利器. ...

  3. 站长在线零基础Python完全自学教程20:在Python中使用正则表达式完全解读

    欢迎你来到站长学堂,学习站长在线出品的在线课程<零基础 Python完全自学教程>今天给大家分享的是第20课< 在Python中使用正则表达式完全解读>.本节课是一个大课,我分 ...

  4. 站长在线Python精讲:在Python中使用正则表达式的sub()方法替换字符串详解

    欢迎你来到站长在线的站长学堂学习Python知识,本文学习的是<在Python中使用正则表达式的sub()方法替换字符串详解>. 在Python中使用正则表达式的sub()方法替换字符串. ...

  5. Python中re(正则表达式)模块函数学习

    2019独角兽企业重金招聘Python工程师标准>>> Python正则表达式指南 今天学习了Python中有关正则表达式的知识.关于正则表达式的语法,不作过多解释,网上有许多学习的 ...

  6. python中的正则表达式是干嘛的_python中正则表达式总结

    re.match():从字符串的开始进行匹配 re.search():扫描整个字符串返回第一个匹配 re.findAll():返回所有匹配的字符串 Pattern 对象不能实例化,只能通过compil ...

  7. Python中利用正则表达式做数据清洗(re)

    目录 1.常用正则表达式 Python中常用正则表达式 2.正则表达式做数据清洗 2.1 从网页HTML标签中提取文本 2.2 去掉英文文章中标点符号,提取词汇 2.3 提取以.com结尾的邮箱 1. ...

  8. Python中的正则表达式(翻译自DiveintoPython3)

    Python中的正则表达式(来自Dive into Python3) 利用python提供的最简单的字符串函数index(), find(), split(), count(), replace()等 ...

  9. 站长在线Python精讲:在Python中使用正则表达式的split()方法分割字符串详解

    欢迎你来到站长在线的站长学堂学习Python知识,本文学习的是<在Python中使用正则表达式的split()方法分割字符串详解>. 使用正则表达式分割字符串 在Python中使用正则表达 ...

最新文章

  1. DNS转发器引起的CDN访问缓慢
  2. 【转】Java中关于异常处理的十个最佳实践
  3. 全球及中国磁滑轮行业规模预测与供应规划研究报告2022版
  4. android获取url参数值,android 获取url 参数值
  5. 时间序列与R语言应用(part5)--移动平均MA模型及其可逆性
  6. Git初学札记(一)————Git简介与安装
  7. 怎么调出matlab的函数,matlab定义函数【搞定方法】
  8. 20200916:leetcode34周双周赛题解
  9. 实验三 类和对象
  10. 在Android中利用iText生成PDF
  11. for 循环中实现多个点击事件
  12. 电脑五笔,电脑键盘五笔指法练习表
  13. Html5实现二维码扫描并解析-web前端教程
  14. 高中计算机考察ppt,高中信息技术考察报告ppt课件.ppt
  15. 电脑安装完软件打不开怎么办
  16. 不会真有人Macbook录屏没声音吧?别用SoundFlower了!
  17. java截取固定大小图片_JAVA技巧(长字符串按指定长度截取)
  18. 关于解决Android系统开发者选项关闭动画后ValueAnimator不生效的问题
  19. 百度千言-中文文本相似度实战
  20. L1-029 是不是太胖了 (5分)

热门文章

  1. js中的history内置对象在各浏览器中的用法:
  2. 【转】:TCP/IP详解学习笔记(4)-ICMP协议,ping和Traceroute
  3. 【C/C++】顺序容器list和vector
  4. getResourceAsStream的3种路径配置
  5. Know more about _in_memory_undo
  6. 你在用MapGuide/Map 3D做什么?
  7. 加入功能区buttonRibbon Button到SP2010特定列表或库
  8. 商业 - 业务领先模型介绍(BLM)
  9. 财务一体化项目,进度与计划31
  10. 02-05 从c到c++