python017 -- 正则表达式
来源:互联网 发布:linux for循环 数组 编辑:程序博客网 时间:2024/06/11 10:16
正则表达式在每种语言中都会有,目的就是匹配符合你预期要求的字符串。
Python正则表达式主要由re库提供,拥有了基本所有的表达式。
16.1 Python正则表达式
.匹配除换行符(\n)之外的任意单个字符字符串123\n456,匹配123:1.3^匹配字符串开头abc\nxyz,匹配以abc开头的行:^abc$匹配字符串结尾abc\nxyz,匹配以xyz结束的行:xyz$*匹配多个hello\nword,匹配以w开头d结尾的单词:w*d+匹配1个或多个abc\nabcc\nadf,匹配abc和abcc:ab+?匹配0个或1个abc\nac\nadd,匹配abc或ac:a?c[.]匹配中括号之中的任意一个字符abcd\nadd\nbbb,匹配abcd和add:[abc][ .-.]匹配中括号中范围内的任意一个字符abcd\nadd\nbbb,匹配abcd和add:[a-c][^]匹配[^字符]之外的任意一个字符abc\n\abb\nddd,不匹配abc和abb:[^a-c]{n}或{n,}匹配花括号前面字符至少n个字符1\n\12\n123\n1234,匹配123和1234:[0-9]{3}{n,m}匹配花括号前面字符至少n个字符,最多m个字符1\n\12\n123\n1234\n12345,匹配123和1234 :[0-9]{3,4}|匹配竖杠两边的任意一个abc\nabd\abe,匹配abc和abd:ab(c|d)\转义符,将特殊符号转成原有意义1.2,匹配1.2:1\.2,否则112也会匹配到\d匹配任意十进制数,等效[0-9]1\n123\nabc,匹配1和123:[0-9],包含单个数字的都会匹配到,如果只想匹配1:\b[0-9]\b\D匹配任意非数字字符,等效[^0-9]1\n12\nabc,匹配abc:[^0-9]\s匹配任意空白字符,等效[\t\n\r\f\v]1\n a,注意a前面有个空格,匹配a:\s\S匹配任意非空白字符,等效[^\t\n\r\f\v]1\n a\n ,匹配1和a:\S\w匹配任意数字和字母,等效[a-zA-Z0-9_]1\n a\n ,匹配1和a:\w\W与\w相反,等效[^a-zA-Z0-9_]
\n反向引用,n是数字,从1开始编号,表示引用第n个分组匹配的内容ff,匹配ff:(.)\1,即"ff"
断言:断言就是一个条件,判断某个字符串前面或后面是否满足某种规律的字符串,不能引用。
16.2 re库
re模块有以下常用的方法:
re.compile(pattern, flags=0)把正则表达式编译成一个对象re.findall(pattern, string, flags=0)以列表形式返回所有匹配的字符串re.finditer(pattern, string, flags=0)以迭代器形式返回所有匹配的字符串re.match(pattern, string, flags=0)匹配字符串开始,如果不匹配返回Nonere.search(pattern, string, flags=0)扫描字符串寻找匹配,如果符合返回一个匹配对象并终止匹配,否则返回Nonere.split(pattern, string, maxsplit=0, flags=0)以匹配模式作为分隔符,切分字符串为列表re.sub(pattern, repl, string, count=0, flags=0)字符串替换,repl替换匹配的字符串,repl可以是一个函数re.purge()清除正则表达式缓存参数说明:
pattern 正则表达式
string 要匹配的字符串
flags 标志位的修饰符,用于控制表达式匹配模式
标志位的修饰符,有以下可选项:
re.DEBUG显示关于编译正则的debug信息re.I/re.IGNORECASE忽略大小写re.L/re.LOCALE本地化匹配,影响\w,\w,\b,\B,\s和\Sre.M/re.MULTILINE多行匹配,影响^和$re.S/re.DOTAIL匹配所有字符,包括换行符\n,如果没这个标志将匹配除了换行符re.U/re.UNICODE根据unicode字符集解析字符。影响影响\w,\w,\b,\B,\d,\D,\s和\Sre.X/re.VERBOSE允许编写更好看、更可读的正则表达式,也可以在表达式添加注释,下面会讲到博客地址:http://lizhenliang.blog.51cto.com
QQ群:323779636(Shell/Python运维开发群)
16.2.1 re.compile()
把正则表达式编译成一个对象,方便再次调用:
>>>
import
re
prog
=
re.
compile
(pattern)
result
=
prog.match(string)
等效于
result
=
re.match(pattern, string)
例如:检查字符串是否匹配
>>>
def
displaymatch(match):
...
if
match
is
None
:
...
return
None
...
return
'<Match: %r, group=%r>'
%
(match.group(), match.groups())
...
>>> valid
=
re.
compile
(r
"^[a-c1-3]{3}$"
)
>>> displaymatch(valid.match(
"a1b"
))
# 可用
"<Match: 'a1b', group=()>"
>>> displaymatch(valid.match(
"a1b2"
))
# 不可用
>>> displaymatch(valid.match(
"bbb"
))
# 可用
"<Match: 'bbb', group=()>"
16.2.1 match()
例如:判断字符串开头是否匹配字符
>>> m
=
re.match(r
'hello'
,
'hello world'
)
>>>
print
m
# 匹配到字符串开头是hello
<_sre.SRE_Match
object
at
0x7f56d5634030
>
>>> m
=
re.match(r
'world'
,
'hello world'
)
>>>
print
m
# 没有匹配到
None
正则对象匹配方法:
1)group([group1, ...])
>>> m
=
re.match(r
'(\w+) (\w+)'
,
'hello world'
)
>>> m.group(
0
)
# 全部组匹配
'hello world'
>>> m.group(
1
)
# 第一个括号子组
'hello'
>>> m.group(
2
)
# 第二个括号子组
'world'
>>> m.group(
1
,
2
)
# 多个参数返回一个元组
(
'hello'
,
'world'
)
通过分子重命名的名字来引用分组结果:
>>> m
=
re.match(r
'(?P<first_name>\w+) (?P<last_name>\w+)'
,
'hello world'
)
>>> m.group(
'first_name'
)
'hello'
>>> m.group(
'last_name'
)
'world'
# 命名组也可以引用他们的索引
>>> m.group(
1
)
'hello'
>>> m.group(
2
)
'world'
如果一组匹配多次,只有最后一个匹配:
>>> m
=
re.match(r
"(..)+"
,
"a1b2c3"
)
>>> m.group(
1
)
'c3'
2)groups([default])
返回一个元组包含所有子组的匹配。
>>> m
=
re.match(r
"(\d+)\.(\d+)"
,
"24.1632"
)
>>> m.groups()
(
'24'
,
'1632'
)
3)groupdict([default])
返回子组名字作为键,匹配结果作为值的字典。
>>> m
=
re.match(r
"(?P<first_name>\w+) (?P<last_name>\w+)"
,
"hello world"
)
>>> m.groupdict()
{
'first_name'
:
'hello'
,
'last_name'
:
'world'
}
4)start()和end()
例如:去掉邮件地址的某字符
>>> email
=
"tony@163_126.com"
>>> m
=
re.search(r
"_126"
, email)
>>> email[:m.start()]
+
email[m.end():]
'tony@163.com'
5)span()
以列表形式返回匹配索引开始和结束值:
>>> email
=
"tony@163_126.com"
>>> m
=
re.search(r
"_126"
, email)
>>> m.span()
(
8
,
12
)
6)pos和endpos
返回字符串开始和结束索引值:
>>> email
=
"tony@163_126.com"
>>> m
=
re.search(r
"_126"
, email)
>>> m.pos
0
>>> m.endpos
16
16.2.3 search()
search()方法也具备match()方法的正则对象匹配方法,区别是search()匹配到第一个后就返回并终止匹配。
例如:匹配第一个结果就返回
>>> m
=
re.search(r
"c"
,
"abcdefc"
)
>>> m.group()
'c'
>>> m.span()
(
2
,
3
)
16.2.4 split()
例如:以数字作为分隔符拆分字符串
>>> m
=
re.split(r
"\d+"
,
"a1b2c3"
)
>>> m
[
'a'
,
'b'
,
'c'
, '']
16.2
.
4
sub()
例如:替换2016
>>> m
=
re.sub(r
"\d+"
,
"2017"
,
"the year 2016"
)
>>> m
'the year 2017'
例如:repl作为一个函数
>>>
def
repl(m):
...
return
str
(
int
(m.group(
'v'
))
*
2
)
...
>>> re.sub(r
'(?P<v>\d+)'
, repl,
"123abc"
)
'246abc'
函数返回必须是一个字符串。
16.2.5 findall()和finditer()
例如:得到所有匹配的数字
>>> text
=
"a1b2c3"
>>> re.findall(r
'\d+'
, text)
[
'1'
,
'2'
,
'3'
]
>>>
for
m
in
re.finditer(r
'\d+'
, text):
...
print
m.group()
...
1
2
3
16.2.6 原始字符串符号"r"
上面所看到的(r"\d+")其中的r代表原始字符串,没有它,每个反斜杠'\'都必须再加一个反斜杠来转义它。
例如,下面两行代码功能上是相同的:
>>> m
=
re.match(r
"\W(.)\1\W"
,
" ff "
)
>>> m.group()
' ff '
>>> m
=
re.match(
"\\W(.)\\1\\W"
,
" ff "
)
>>> m.group()
' ff '
>>> m
=
re.match(
"\W(.)\1\W"
,
" ff "
)
>>> m.group()
Traceback (most recent call last):
File
"<stdin>"
, line
1
,
in
<module>
AttributeError:
'NoneType'
object
has no attribute
'group'
\W匹配第一个和最后一个空字符,(.)匹配第一个f,\1引用前面(.)匹配的结果(还是f),即是r"ff"
16.3 贪婪和非贪婪匹配
贪婪模式:尽可能最多匹配
非贪婪模式,尽可能最少匹配,一般在量词(*、+)后面加个问号就是非贪婪模式。
# 贪婪匹配
>>> re.findall(r
"<div>.*</div>"
,
"<div>a</div><div>b</div><div>c</div>"
)
[
'<div>a</div><div>b</div><div>c</div>'
]
# 非贪婪匹配
>>> re.findall(r
"<div>.*?</div>"
,
"<div>a</div><div>b</div><div>c</div>"
)
[
'<div>a</div>'
,
'<div>b</div>'
,
'<div>c</div>'
]
>>> re.findall(r
"a(\d+)"
,
"a123b"
)
[
'123'
]
>>> re.findall(r
"a(\d+?)"
,
"a123b"
)
[
'1'
]
# 如果右边有限定,非贪婪失效
>>> re.findall(r
"a(\d+)b"
,
"a123b"
)
[
'123'
]
>>> re.findall(r
"a(\d+?)b"
,
"a123b"
)
[
'123'
]
贪婪匹配是尽可能的向右匹配,直到字符串结束。
非贪婪匹配是匹配满足后就结束。
16.3 了解扩展表达式
以一个字符串来学习断言的用法:"A regular expression "
1)(?=...)
正先行断言,匹配后面能匹配的表达式。
有两个re字符串,只想匹配regular中的:
>>> re.findall(r
"..(?=gular)"
,
"A regular expression"
)
[
're'
]
# 再向后匹配几个字符说明匹配的regular中的。下面都会说明下,不再注释
>>> re.findall(r
"(?=gular).{5}"
,
"A regular expression"
)
[
'gular'
]
2)(?!...)
负先行断言,匹配后面不能匹配表达式。
只想匹配expression中的re字符串,排除掉regular单词:
>>> re.findall(r
"re(?!g)"
,
"A regular expression"
)
[
're'
]
>>> re.findall(r
"re(?!g).{5}"
,
"A regular expression"
)
[
'ression'
]
3)(?<=...)
正向后行断言,匹配前面能匹配表达式。
只想匹配单词里的re,排除开头的re:
>>> re.findall(r
"(?<=\w)re"
,
"A regular expression"
)
[
're'
]
>>> re.findall(r
"(?<=\w)re."
,
"A regular expression"
)
[
'res'
]
在re前面有一个或多个字符,所以叫后行断言,正则匹配是从前向后,当遇到断言时,会再向字符串前端检测已扫描的字符,相对于扫描方向是向后的。
4)(?<!...)
负向后行断言,匹配前面不能匹配的表达式。
只想匹配开头的re:
>>> re.findall(r
"(?<!\w)re"
,
"A regular expression"
)
[
're'
]
>>> re.findall(r
"(?<!\w)re."
,
"A regular expression"
)
[
'reg'
]
16.4 修饰符
re.VERBOSE上面说明可能你还不太明白,怎么个更加可读呢,这就来看看,下面两个正则编译等效:
>>> a
=
re.
compile
(r
"""\d + # the integral part
... \. # the decimal point
... \d * # some fractional digits"""
, re.X)
>>> b
=
re.
compile
(r
"\d+\.\d*"
)
当你写的正则很长的时候,可以添加注释。
Python正则表达式参考:https://docs.python.org/2/library/re.html
- python017 -- 正则表达式
- [2015-08-06] python017
- python017 Python3 模块
- 【正则表达式】正则表达式
- 正则表达式
- 正则表达式
- 正则表达式
- 正则表达式
- 正则表达式
- 正则表达式
- 正则表达式
- 正则表达式
- 正则表达式
- 正则表达式
- 正则表达式
- 正则表达式
- 正则表达式
- 正则表达式
- ABAP 关于ALV布局保存选项的讲解
- 蓝桥杯 BASIC-11 基础练习 十六进制转十进制
- java-swing初探
- phpstorm在项目中查找某个字符串
- toolbar中设定左上角按钮及其点击事件的顺序的原因
- python017 -- 正则表达式
- UDP
- 堆结构的优秀实现类----PriorityQueue优先队列
- MVC、MVP、MVVM、Angular.js、Knockout.js、Backbone.js、React.js、Ember.js、Avalon.js、Vue.js 概念摘录
- PAT--1038. Recover the Smallest Number
- 使用MyEclipse创建第一个Hibernate实例
- 蓝桥杯 BASIC-10 基础练习 十进制转十六进制
- js移除元素所有click绑定事件
- MYSQL替换字段中敏感字符