赞
踩
正则表达式是 处理字符串的强大工具,拥有独特的语法和独立的处理引擎。
典型的搜索和替换操作要求提供与预期的搜索结果匹配的确切文本。虽然这种技术对于对静态文本执行简单搜索和替换任务可能已经足够了,但它缺乏灵活性,若采用这种方法搜索动态文本,即使不是不可能,至少也会变得很困难。
通过使用正则表达式,可以:
正则表达式是一种文本模式,包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为"元字符")。使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。
效率上可能不如str自带的方法,但匹配功能实在强大太多。另外,正则表达式不是Python独有的,如果已经在其他语言里使用过正则表达式,这里的说明只需要简单看一看就可以上手啦。
这里有一份正则表达式小抄,即我们在写正则表达式时可以参考以下图表内容。
字符
模式 | 描述 |
---|---|
. | 匹配任意字符,除了\n。当re.DOTALL标记被指定时,就可以匹配含换行符的任意字符。 |
[…] | 字符集。 字符集中的字符可以逐个列出,也可以给出范围,例如[abc]或[a-c] |
[^…] | 匹配不在[ ]中的字符,例如[^abc] 匹配除了a,b,c之外的字符。 |
预定义字符集(也可以写在字符集[…]中)
模式 | 描述 |
---|---|
\d | 匹配任意数字====[0-9] |
\D | 匹配任意非数字====[^\d] |
\s | 匹配任意空白字符,包括空格、制表符、换页符等等。====[\t\n\r\f] |
\S | 匹配任意非空字符====[^\s] |
\w | 匹配字母数字及下划线====[A-Za-z0-9_] |
\W | 匹配非字母数字及下划线====[^\w] |
数量词 用在字符或者(…)之后
模式 | 描述 |
---|---|
* | 匹配0个或多个的表达式 |
+ | 匹配1个或多个的表达式。 |
? | 匹配0个或1个由前面的正则表达式定义的片段,非贪婪方式 |
{m} | 精确匹配 m个前面表达式。例如, o{2} 不能匹配 “Bob” 中的 “o”,但是能匹配 “food” 中的两个 o。 |
{m,} | 匹配 m 个前面表达式。例如, o{2,} 不能匹配"Bob"中的"o",但能匹配 "foooood"中的所有 o。“o{1,}” 等价于 “o+”。“o{0,}” 则等价于 “o*”。 |
{m,n} | 匹配m到n次由前面的正则表达式定义的片段,贪婪方式 |
边界匹配
模式 | 描述 |
---|---|
^ | 匹配字符串的开头。在多行模式中,匹配每一行的开头。 |
$ | 匹配字符串的末尾。在多行模式中,匹配每一行的末尾。 |
\A | 仅匹配字符串开始 |
\Z | 仅匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串。 |
\b | 匹配一个单词边界,也就是指单词和空格间的位置。例如, ‘er\b’ 可以匹配"never" 中的 ‘er’,但不能匹配 “verb” 中的 ‘er’。 |
\B | 匹配非单词边界。‘er\B’ 能匹配 “verb” 中的 ‘er’,但不能匹配 “never” 中的 ‘er’。 |
【补充】
1.数量词的贪婪匹配和非贪婪匹配
Python里数量词默认是贪婪的(在少数语言里也可能是默认非贪婪),总是尝试匹配尽可能多的字符;非贪婪的则相反,总是尝试匹配尽可能少的字符。例如:正则表达式"ab*“如果用于查找"abbbc”,将找到"abbb"。而如果使用非贪婪的数量词"ab*?",将找到"a"。即贪婪为 .* ,非贪婪为 .* ?。
2.验证工具
正则表达式在线验证工具之一是 http://regexr.com/
3.正则表达式在线练习
https://regexr.com/
https://alf.nu/RegexGolf
re = regular experssion
re 模块使 Python 语言拥有全部的正则表达式功能。
compile 函数根据一个模式字符串和可选的标志参数生成一个正则表达式对象。该对象拥有一系列方法用于正则表达式匹配和替换。
re 模块也提供了与这些方法功能完全一致的函数,这些函数使用一个模式字符串做为它们的第一个参数。
本章节主要介绍Python中常用的正则表达式处理函数。
match尝试从字符串的起始位置开始匹配;
函数语法:
re.match(pattern,string,flags=0)
函数参数说明:
参数 | 描述 |
---|---|
pattern | 匹配的正则表达式 |
string | 要匹配的字符串 |
flags | 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等 |
正则表达式修饰符-可选标志flags:
修饰符 | 描述 |
---|---|
re.I | 使匹配对大小写不敏感 |
re.L | 做本地化识别(locale-aware)匹配 |
re.M | 多行匹配,影响 ^ 和 $ |
re.S | 使 . 匹配包括换行在内的所有字符 |
re.U | 根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B. |
匹配成功re.match方法返回一个匹配的对象,否则返回None。
我们可以使用group(num) 或 groups() 匹配对象函数来获取匹配表达式。
import re
aObj = re.match(r'we', 'we are Chinese')
print(aObj)
print(aObj.group())
执行效果如下:
匹配对象方法 | 描述 |
---|---|
group(num=0) | 匹配的整个表达式的字符串,group() 可以一次输入多个组号,在这种情况下它将返回一个包含那些组所对应值的元组。 |
groups( ) | 返回一个包含所有小组字符串的元组,从 1 到 所含的小组号。 |
group( ) 返回被 re 匹配的字符串。
import re
print(re.match('www', 'www.runoob.com').span()) # 在起始位置匹配
print(re.match('www', 'www.runoob.com').start())
print(re.match('www', 'www.runoob.com').end())
print(re.match('com', 'www.runoob.com')) # 不在起始位置匹配
执行效果如下:
import re
line = "Cats are smarter than dogs"
matchObj = re.match(r'(.*) are (.*?) .*', line, re.M | re.I)
#标志位的设置,在前面表格flags
if matchObj:
print("matchObj.group() : ", matchObj.group())
print('matchObj.group(1) :', matchObj.group(1))
print('matchObj.group(2) :' , matchObj.group(2))
print("matchObj.group(1,2) : ", matchObj.group(1,2))
print("matchObj.groups() : ", matchObj.groups())
else:
print('no match!')
执行效果如下:
扫描整个字符串并返回第一个成功的匹配。
函数语法:
re.search(pattern, string, flags=0)
函数参数说明:
参数 | 描述 |
---|---|
pattern | 匹配的正则表达式 |
string | 要匹配的字符串 |
flags | 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等 |
匹配成功re.search方法返回一个匹配的对象,否则返回None。
我们可以使用group(num) 或 groups() 匹配对象函数来获取匹配表达式。
匹配对象方法 | 描述 |
---|---|
group(num=0) | 匹配的整个表达式的字符串,group() 可以一次输入多个组号,在这种情况下它将返回一个包含那些组所对应值的元组。 |
groups( ) | 返回一个包含所有小组字符串的元组,从 1 到 所含的小组号。 |
import re
print(re.search('www', 'www.runoob.com').span()) # 在起始位置匹配
print(re.search('com', 'www.runoob.com').span()) # 不在起始位置匹配
执行效果如下:
读者可以将这个例子的search和match对照着执行,会发现search在起始位置没有匹配到是会接着往下匹配,直到真的没有匹配到才会返回None,而match在起始位置没有匹配到时就直接返回None。因此如果没有在起始位置匹配时,match接收到的是None,不能再调用span()。
re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search匹配整个字符串,直到找到一个匹配。
import re
line = "Cats are smarter than dogs"
matchObj = re.match(r'dogs', line, re.M | re.I)
if matchObj:
print("match --> matchObj.group() : ", matchObj.group())
else:
print("match --> matchObj.group() : No match!!")
matchObj = re.search(r'dogs', line, re.M | re.I)
if matchObj:
print("search --> matchObj.group() : ", matchObj.group())
else:
print("search --> matchObj.group() : No match!!")
执行效果如下:
Python 的 re 模块提供了re.sub用于替换字符串中的匹配项。
函数语法:
re.sub(pattern, repl, string, count=0, flags=0)
函数参数说明:
参数 | 说明 |
---|---|
pattern | 正则中的模式字符串。 |
repl | 替换的字符串,也可为一个函数。 |
string | 要被查找替换的原始字符串。 |
count | 模式匹配后替换的最大次数,默认 0 表示替换所有的匹配。 |
import re
phone = "2004-959-559 # 这是一个国外电话号码"
# 删除字符串中的 Python注释
num = re.sub(r'#.*$', '', phone)
print("电话号码是: ", num)
# 删除非数字(-)的字符串
num = re.sub(r'\D','', phone)
print("电话号码是 : ", num)
执行效果如下:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。