Python Revisited Day 13 (正则表达式)
《Python 3 程序开发指南》 学习笔记
13.1 Python的正则表达式语言
13.1.1 字符与字符类
特殊字符:\.^$?+*{}|
在一个字符类内部,除\外,特殊字符不再具备特殊意义.
当^ 为一个字符类的第一个字符时,表其特殊含义否定。
-表示一个字符范围,如果作为字符类中的第一个字符,就表示一个字面意义上的连字符。
字符类速记(表)
符号 | 含义 |
---|---|
. | 可以匹配除换行符之外的任意字符,或带re.DOTALL标记的任意字符,或匹配字符内部的字面意义的字符。 |
\d | 匹配一个Unicode数字,或带(等价于的意思?)re.ASCII标记的[0-9] |
\D | 匹配一个Unicode非数字,或带re.ASCII标记的[0-9] |
\s | 匹配Unicode空白,或带re.ASCII标记的[\t\n\r\f\v] |
\S | 匹配Unicode非空白,或带re.ASCII标记的[^\t\n\r\f\v] |
\w | 匹配一个Unicode单词字符,或带re.ASCII标记的[a-zA-Z0-9] |
\W | 匹配一个Unicode非单词字符,或带re.ASCII标记的[^a-zA-Z0-9] |
13.1.2 量词 {m, n} ? + *
{m, n}:m表示该量词必须匹配的最小次数,而n表示最多次数,如e{1,1}, e{2, 2}
如果m, n相同,可以简写为{m}。而量词{0,1}有一种速记形式?.
travell{0,1}ed == travell?ed
正则表达式量词(表)
语法 | 含义 |
---|---|
e? or e{0,1} | 贪婪地匹配表达式e的0或1次出现 |
e?? or e{0,1}? | 非贪婪地匹配表达式e e+或{1,}的0次或1次出现,贪婪地匹配表达式e的1次或多次出现 |
e+? or e{1,}? | 非贪婪地匹配表达式e的一次或多次出现 |
e* or e{0,} | 贪婪地匹配表达式e的0次或1次出现 |
e*? or e{0,}? | 非贪婪地匹配表达式e地0次或1次出现 |
e{m} | 准确匹配表达式e的m次出现 |
e{m,} | 贪婪地匹配表达式e的至少m次出现 |
e{m,}? | 非贪婪地匹配表达式e的至少m次出现 |
e{,n} | 贪婪地匹配表达式e的至多n次出现 |
e{,n}? | 非贪婪地匹配表达式e的至多n次出现 |
e{m,n} | 贪婪地匹配表达式e的至少m次,至多n次出现 |
e+ | e{1,n}(至少一次),n是量词地可能地最大值,通常是32767 |
e* | e{0,n}(任意次),n同上 |
e{m,n}? | 非贪婪地匹配表达式e地至少m次,至多n次出现 |
- 默认情况下,所有量词都是贪婪的,量词后面跟随?表示非贪婪。
re.match(r"\d+", "136")
#<re.Match object; span=(0, 3), match='136'>
re.match(r"\d+?", "136")
#<re.Match object; span=(0, 1), match='1'>
re.match(r"\d??", "136")
#<re.Match object; span=(0, 0), match=''>
re.match(r"\d{0,1}?", "136")
#<re.Match object; span=(0, 0), match=''>
re.match(r"\d{0,1}?36", "136")
#<re.Match object; span=(0, 3), match='136'>
re.match(r"\d*?", "136")
#<re.Match object; span=(0, 0), match=''>
re.match(r"\d*?6", "136")
#<re.Match object; span=(0, 3), match='136'>
re.match(r"<img\s+[^>]*?src=\w[^>]*?>", "<img src=dd>")
#<re.Match object; span=(0, 14), match='<img src=dd>'>
组与捕获 ?:可以关闭捕获
()可以进行分组,而交替字符|在多种方案中选取一个的情况下使用。
re.match(r"aircraft|airplane|jet", "airplane")
#<re.Match object; span=(0, 8), match='airplane'>
re.match(r"air(craft|plane)|jet", "airplane")
#<re.Match object; span=(0, 8), match='airplane'>
()在分组的同时进行捕获,以备后用。
for i in range(3):
print(re.match(r"(air(craft|plane)|jet)", "airplane")[i])
#airplane #只要匹配成功,首项都是完整匹配项
#airplane
#plane
try:
for i in range(3):
print(re.match(r"(air(?:craft|plane)|jet)", "airplane")[i]) #?:关闭捕获
except IndexError as err:
print("IndexError: {0}".format(err))
#airplane
#airplane
#IndexError: no such group
s = "eric1 = something\n"\
"eric2 = somewhere\n"\
"eric3 = somebody"
try:
for i in range(10):
print(re.match(r"(\w+ = .+\n?)+", s)[i])
except IndexError as err:
print("IndexError: {0}".format(err))
#eric1 = something
#eric2 = somewhere
#eric3 = somebody
#eric3 = somebody
#IndexError: no such group
s = "eric1 = something\n"\
"eric2 = somewhere\n"\
"eric3 = somebody"
try:
for i in range(10):
print(re.match(r"(?:(\w+) = (.+)\n?)+", s)[i])
except IndexError as err:
print("IndexError: {0}".format(err))
#eric1 = something
#eric2 = somewhere
#eric3 = somebody
#eric3
#somebody
#IndexError: no such group
反向引用 \i 反向引用不能用在字符类内部,即不能用在[]中
re.match(r"(\w+)\s+\1", "eric eric")
#<re.Match object; span=(0, 9), match='eric eric'>
re.match(r"(\w+)(\d?)\s+\1\2", "eric1 eric1")
#<re.Match object; span=(0, 11), match='eric1 eric1'>
re.match(r"(\w+)(\d?)\s+\1\2", "eric1 eric2") # None
命名捕获 (?P...) 反向引用:(?P=name)
- 注意, (?P=name)只是匹配,((?P=name))才能完成捕获
for item in ('name', 'what'):
print(re.match(r"(?P<name>\w+)\s+(?P<what>\w+)", "Pikachu Pokemon")[item])
#Pikachu
#Pokemon
re.match(r"(?P<name>\w+)\s+((?P=name))", "Pikachu Pikachu")[2]
#'Pikachu'
断言与标记
符号 | 含义 |
---|---|
^ | 在起始处匹配,也可以在带MULTILINE标记的每个换行符后匹配 |
$ | 在结尾处匹配,也可以在MULTILINE标记的每个换行符前匹配 |
\A | 在起始处匹配 |
\b | 在单词边界匹配,受re.ASCII标记影响——在字符类内部,则是backspace字符的转义字符 |
\B | 在非单词边界匹配,受re.ASCII标记影响 |
\Z | 在结尾处匹配 |
(?=e) | 如果表达式e在此断言处匹配,但没有超越此处——称为前瞻或正前瞻,则匹配 |
(?!e) | 如果表达式e在此前言处不匹配,也没有超越此处——称为负前瞻,则匹配 |
(?<=e) | 如果表达式e恰在本断言之前匹配——成为正回顾,则匹配 |
(?<!e) | 如果表达式e恰在本断言之前不匹配——称为负回顾,则匹配 |
- 单词边界,顾名思义就是该位置为单词的边界,比如\b位置之前是一个单词,后面是非单词(比方空格),当然反过来也是可以的。
re.match(r"eric", "eric1")
#<re.Match object; span=(0, 4), match='eric'>
re.match(r"eric\b", "eric1") #None
re.match(r"deric", "deric1")
#<re.Match object; span=(0, 5), match='deric'>
re.match(r"d\beric", "deric1") #None
s = "I'm sorry, my son.\n Actually, actually, she is my daughter, and your sister..."
re.match(r".+(?<=son)", s)
#<re.Match object; span=(0, 17), match="I'm sorry, my son">
s = "I'm sorry, my son.\n Actually, actually, she is my daughter, and your sister..."
re.match(r".+(?<!daugther)", s)
#<re.Match object; span=(0, 18), match="I'm sorry, my son.">
条件性匹配 (?(id)yes_exp) | (?(id)yes_exp|no_exp)
s1 = "src=\"ddd.ddd\""
s2 = "src='ddd.ddd'"
s3 = "src=ddd.ddd"
re.match(r"src=([\"'])([^\"'>]+)\1", s1) # ! s3
#<re.Match object; span=(0, 13), match='src="ddd.ddd"'>
re.match(r"src=([\"'])?([^\"'>]+)(?(1)\1)", s3)
#<re.Match object; span=(0, 11), match='src=ddd.ddd'>
设置标记 (?flags) flags == a | i | m| s | x
符号 | 含义 |
---|---|
a | re.ASCII |
i | re.IGNORECASE |
m | re.MULTILINE |
s | re.DOTALL |
x | re.VERBOSE |
13.2 正则表达式模块
正则表达式模块的函数(表)
语法 | 描述 |
---|---|
re.compile(r, f) | 返回编译后的正则表达式r,如果指定,就将其标记设置为f |
re.escape(s) | 返回字符串s,其中所有非字母数字的字符都是用反斜线进行了转义处理,因此返回的字符串中没有特殊的正则表达式字符 |
re.findall(r, s, f) | 返回正则表达式r在字符串s中所有非交叠的匹配(如果给定f,就受其值约)。如果正则表达式中有捕获,那么每次匹配都作为一个捕获元组返回 |
re.finditer(r, s, f) | 对正则表达式r在字符串s中每个非交叠的匹配(如果给定f,就受其值约),都返回一个匹配对象 |
re.match(r, s, f) | 如果正则表达式r在字符串s的起始处匹配(如果给定f,就受其制约),就返回一个匹配对象,否则返回None |
re.search(r, s, f) | 如果正则表达式r在字符串s的任意位置处匹配(如果给定f,就受其值约),就返回一个匹配对象,否则返回None |
re.split(r, s, m) | 返回分割字符串s(在正则表达式r每次出现出进行分割)所产生的字符串的列表,至多分割m次(如果没有给定m,就分割尽可能多的次数),如果正则表达式中包含捕获,就被包含在分割的部分之间 |
re.sub(r, x, s, m) | 对正则表达式r的每次匹配(如果给定m,那么至多m次),返回字符串s的一个副本,并将其替换为x——这可以是一个字符串,也可以是一个函数 |
re.subn(r, x, s, m) | 与re.sub()函数相同,区别在于此函数返回一个二元组,其中一项为生成的字符串,一项为代入的次数 |
import re
re.escape("\\") #'\\\\'
s = "eric1 = something\n"\
"eric2 = somewhere\n"\
"eric3 = somebody"
try:
for i in range(10):
print(re.findall(r"(?:(\w+) = (.+)\n?)+", s)[i])
except IndexError as err:
print("IndexError: {0}".format(err))
#('eric3', 'somebody')
#IndexError: list index out of range
#从下面的例子可以明白什么是非交叠匹配
s = "bigbigericbigbig\n"\
"smallsmallericsmallsmall\n"\
"hardharderichardhard"
e = r"""(?x)(?i)
((?P<attr>big|small)(eric)\2)
"""
e = re.compile(e)
re.findall(e, s) #[('bigericbig', 'big', 'eric'), ('smallericsmall', 'small', 'eric')]
s = "eric1 = something\n"\
"eric2 = somewhere\n"\
"eric3 = somebody"
re.split(r"\n", s)
#['eric1 = something', 'eric2 = somewhere', 'eric3 = somebody']
正则表达式模块的标记(表)
标记 | 含义 |
---|---|
re.A or re.ASCII | 使\b,\B,\s,\S,\w,\W都假定字符串为ASCII,默认为这些字符类的速记法,依赖于Unicode规范 |
re.I or re.IGNORECASE | 使正则表达式以大小写不敏感的方法进行匹配 |
re.M or re.MULTILINE | 使^在起始处并在每个换行符后匹配,使$在结尾处但在每个换行符之前匹配 |
re.S or re.DOTALL | 使.匹配每个字符,包括换行符 |
re.X or re.VERBOSE | 使空白和注释包含在匹配中 |
s = "eric1=something\n"\
"eric2 = somewhere\n"\
"Eric3 = somebody"
re.findall(r"eric", s, re.I)
#['eric', 'eric', 'Eric']
e = r"""(?x)
(?P<eric>eric)
"""
e = re.compile(e)
e.findall(s)
#['eric', 'eric']
正则表达式对象方法(表)
rx表正则表达式,下面的方法其实上面都有提到过。
语法 | 描述 |
---|---|
rx.findall(s, start, end) | 返回字符串s中(或s的start:end分片中)正则表达式的所有非交叠的匹配,如果正则表达式有捕获,那么每次匹配是返回一个捕获元组 |
rx.finditer(sstart, end) | 对字符串s中(或s的start:end分片中)的每个非交叠匹配,返回一个匹配对象 |
rx.flags | 正则表达式编译时设置的标记 readonly |
rx.groupindex | 一个字典,其键位捕获组名,值为捕获组编号,如果没有使用名称就为空 |
rx.match(s, start, end) | 如果正则表达式在字符串s的起始处(或s的start:end分片起始处)匹配,就返回一个匹配对象,否则返回None |
rx.pattern | 正则表达式被编译时使用的字符串 |
rx.search(s, start, end) | 如果正则表达式在字符串s的任意位置(或s的start:end分片中的任意位置)匹配,就返回一个匹配对象,否则返回None |
rx.split(s, m) | 返回字符串列表,其中每个字符串都源自对字符串s的分割(在正则表达式的每次匹配处),但至多有m个分割(如果没有给定m,则可以有尽可能多的分割);如果正则表达式有捕获,就包含在列表中俩个分割之间 |
rx.sub(x, s, m) | 返回字符串s的副本,其中每个(或至多m个,如果给定)匹配出使用x(可以时字符串或函数)进行替换 |
rx.subn(x, s, m) | 与rx.sub()相同,区别在于返回的是二元组,其中一项时结果字符串,一项时所做替换的个数 |
e.groupindex
#mappingproxy({'eric': 1})
e.pattern
#'(?x)\n (?P<eric>eric)\n'
匹配对象的属性与方法(表)
m 匹配对象——finditer, match等方法可能返回匹配对象
语法 | 描述 |
---|---|
m.end(g) | 返回组g(如果给定)在文本中匹配的终点索引位置,对组0,则表示整体匹配;如果匹配中不包含改组,就返回-1 |
m.endpos | 搜索的终点索引位置(文本的重点,或赋予match()或search()的end |
m.expand(s) | 返回字符串s,并将其中的捕获标志(\1, \2, \g等类似的标志)用相应的捕获替代 经测试如果s== r"..."上述可行,如果s是普通的字符串,应当用:\1, \2, \g,没错除了\g外需要转义 |
m.group(g, ...) | 返回编号的或命名的组g,如果给定的不止一个,就返回相应的捕获组成的元组(组0表示整体匹配) |
m.groupdict(default) | 返回一个字典,其中存放所有命名的捕获组,组名作为键,捕获作为值;如果给定了default参数,就将其用作那些不参与匹配的捕获组的值 |
m.groups(default) | 返回包含所有捕获组的元组,从1开始;如果给定default,就将其用作那些不参与匹配的捕获组的值 |
m.lastgroup | 匹配的,编号最高的捕获组的名称,如果不存在或没使用名称,就返回None |
m.lastindex | 匹配的,编号最高的捕获组的编号,如果没有就返回None |
m.pos | 搜索的起始索引位置(文本的起始处,或赋予match()或search()的start) |
m.span(g) | 如果给定g,就返回组g在文本中匹配的起始索引位置与结尾索引位置(对组0,则是整体匹配);如果改组不参加匹配,就返回(-1,-1) |
m.start(g) | 如果给定g,就返回组g在文本中匹配的起始索引位置(对组0,则是整体匹配);如果改组不参加匹配,就返回01 |
m.string | 船体给match()或search()的字符串 |
s = "bigbigericbigbig\n"\
"smallsmallericsmallsmall\n"\
"hardharderichardhard"
e = r"""(?x)(?i)
((?P<attr>big|small)(eric)\2)
"""
e = re.compile(e)
ms = re.finditer(e, s)
for m in list(ms):
print(m.end(2), m.endpos)
#6 62
#27 62
s2 = "\g<attr>pig"
s3 = "\\2cat"
s4 = r"\2cat"
ms = re.finditer(e, s)
print(next(ms).expand(s2))
m = next(ms)
print(m.expand(s3), m.expand(s4))
#bigpig
#smallcat smallcat
m.group(), m.group(1), m.group(1, 2, 3)
#('smallericsmall', 'smallericsmall', ('smallericsmall', 'small', 'eric'))
m.groupdict()
#{'attr': 'small'}
m.groups()
#('smallericsmall', 'small', 'eric')
m.lastgroup #None
m.lastindex #1
m.span(), m.span(1), m.span(2), m.span(3)
#((22, 36), (22, 36), (22, 27), (27, 31))
m.string
#'bigbigericbigbig\nsmallsmallericsmallsmall\nhardharderichardhard'
Python Revisited Day 13 (正则表达式)的更多相关文章
- Python学习:13.Python正则表达式
一.正则表达式简介 正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配. Python 自1.5版本起增加了re 模块,它提供 Perl 风格的正则表达式模式. 就其本质 ...
- Python标准库01 正则表达式(re包)
python正则表达式基础 简单介绍 正则表达式并不是python的一部分.正则表达式是用于处理字符串的强大工具,拥有自己独特的语法及一个独立的处理引擎,效率上可能不如str自带的方法,但功能十分强大 ...
- python基础之 re(正则表达式)模块学习
今天学习了Python中有关正则表达式的知识.关于正则表达式的语法,不作过多解释,网上有许多学习的资料.这里主要介绍Python中常用的正则表达式处理函数. re.match re.match 尝试从 ...
- python字符串转义与正则表达式特殊字符转义
最近在自学python,字符串和正则表达式的特殊字符转义有点混淆,做个笔记简单总结一下. 1.普通字符串转义 在字符串中使用特殊字符时,要用反斜杠(\)转义字符.例如:'Let\'s go!',这里对 ...
- python爬虫之re正则表达式库
python爬虫之re正则表达式库 正则表达式是用来简洁表达一组字符串的表达式. 编译:将符合正则表达式语法的字符串转换成正则表达式特征 操作符 说明 实例 . 表示任何单个字符 [ ] 字符集,对单 ...
- python与JavaScript中正则表达式如何转换
使用python爬取网站数据的时候,总会遇到各种各样的反爬虫策略,有很大一部分都和JavaScript(以下简称为JS) 有关.在破解这些JS代码的过程中,经常会遇到模拟JS正则表达式的情况,因此,今 ...
- Python编程中 re正则表达式模块 介绍与使用教程
Python编程中 re正则表达式模块 介绍与使用教程 一.前言: 这篇文章是因为昨天写了一篇 shell script 的文章,在文章中俺大量调用多媒体素材与网址引用.这样就会有一个问题就是:随着俺 ...
- python基础之坑爹正则表达式
python基础之坑爹正则表达式 概述 re模块就是python语言中的正则表达式,拆出来单独写一条blog是因为正则表达式本身就是比较庞大的知识,写具体些让自己以后方便查找. IP: ^(25[0- ...
- 【Python开发】Python之re模块 —— 正则表达式操作
Python之re模块 -- 正则表达式操作 这个模块提供了与 Perl 相似l的正则表达式匹配操作.Unicode字符串也同样适用. 正则表达式使用反斜杠" \ "来代表特殊形式 ...
随机推荐
- C#委托与事件学习笔记
委托事件学习笔记 本文是学习委托和事件的笔记,水平有限,如有错漏之处,还望大神不吝赐教. 什么是委托?从字面意思来解释,就是把一个动作交给别人去执行.在实际开发中最常用的就是使一个方法可以当做一个参数 ...
- [转]BAT 批处理脚本 教程
第一章 批处理基础第一节 常用批处理内部命令简介 批处理定义:顾名思义,批处理文件是将一系列命令按一定的顺序集合为一个可执行的文本文件,其扩展名为BAT或者CMD.这些命令统称批处理命令.小知识:可以 ...
- [日常] nginx的错误日志error_log设置
nginx error_log设置1.error_log syslog:server=192.168.1.1 [级别] //直接发送给远程syslog日志集中服务器2.error_log stderr ...
- Win10系统简单开启热点
介绍 笔记本电脑使用的都是无线网卡,我们可以通过这网卡来开启热点供手机使用,说起开热点,大家都是想到的使用360随身wifi或者是猎豹wifi来开启热点吧,我个人不太喜欢使用这些软件,原因因为有DNS ...
- Chrome 下input的默认样式
一.去除默认边框以及padding border: none;padding:0 二.去除聚焦蓝色边框 outline: none; 三.form表单自动填充变色 1.给input设置内置阴影,至少要 ...
- [总结]WEB前端开发常用的CSS/CSS3知识点
css3新单位vw.vh.vmin.vmax vh: 相对于视窗的高度, 视窗被均分为100单位的vh; vw: 相对于视窗的宽度, 视窗被均分为100单位的vw; vmax: 相对于视窗的宽度或高度 ...
- 驰骋工作流引擎JFlow与activiti的对比之2种结构化模式
1. 任意循环(Arbitrary Cycles) ACTIVITI : 某一个或多个活动可以反复执行. 例子:用户买了瓶汽水,拿到汽水后,中了一瓶,又去兑换了一瓶汽水,如果又中了,再去兑换一瓶汽水- ...
- 深入理解Java内存(图解堆栈)
深入理解Java内存(图解)--转载 深入理解Java内存(图解) 这篇文章是转自http://blog.csdn.net/shimiso/article/details/8595564博文,自己对其 ...
- 当我们按下电源键,Android 究竟做了些什么?
欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由goo发表于云+社区专栏 相信我们对Android系统都不陌生,而Android系统博大精深,被各种各样的智能设备承载的同时,我们会否 ...
- gitbook 入门教程之实用插件(新增3个插件)
插件没有什么逻辑顺序,大家可以按照目录大纲直接定位到感兴趣的插件部分阅读即可. 更多插件正在陆续更新中,敬请期待... 最新更新插件 tbfed-pagefooter 版权页脚插件 gitalk 评论 ...