正则表达式常用方法
正则表达式本身是一种小型的、高度专业化的编程语言,而在python中,通过内嵌集成re模块,程序猿 们可以直接调用来实现正则匹配。正则表达式模式被编译成一系列的字节码,然后由用C编写的匹配引擎执行。
主要功能:
1.校验功能,账户 密码 电话 邮箱 ip地址
2.在目标字符串中匹配想要的字符
常用方法:
compile()
编译正则表达式模式,返回一个对象的模式。(可以把那些常用的正则表达式编译成正则表达式对象,这样可以提高一点效率。)
格式:re.compile(pattern,flags=0)
pattern: 编译时用的表达式字符串。
flags 编译标志位,用于修改正则表达式的匹配方式,如:是否区分大小写,多行匹配等。常用的flags有:
标志 | 含义 |
re.S(DOTALL) | 使.匹配包括换行在内的所有字符 |
re.I(IGNORECASE) | 使匹配对大小写不敏感 |
re.L(LOCALE) | 做本地化识别(locale-aware)匹配,法语等 |
re.M(MULTILINE) | 多行匹配,影响^和$ |
re.X(VERBOSE) | 该标志通过给予更灵活的格式以便将正则表达式写得更易于理解 |
re.U | 根据Unicode字符集解析字符,这个标志影响\w,\W,\b,\B |
search:扫描整个字符串并返回第一个成功的匹配。
格式: re.search(pattern, string, flags=0)
match : 默认在规则加^,尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话match()就返回none。
格式:re.match(pattern, string, flags=0)
string 要匹配的字符串。
findall :在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表。
格式:findall(string[, pos[, endpos]])
string : 待匹配的字符串。
pos : 可选参数,指定字符串的起始位置,默认为 0。
endpos : 可选参数,指定字符串的结束位置,默认为字符串的长度。
注意: match 和 search 是匹配一次 findall 匹配所有。
替换:
Python 的 re 模块提供了re.sub用于替换字符串中的匹配项。
语法:re.sub(pattern, repl, string, count=0, flags=0)
pattern : 正则中的模式字符串。
repl : 替换的字符串,也可为一个函数。
string : 要被查找替换的原始字符串。
count : 模式匹配后替换的最大次数,默认 0 表示替换所有的匹配。
常用规则
\d : 匹配一个数字
\w : 匹配一个数字字母下划线
\s : 匹配空格
\D : 匹配非 \d
\W : 匹配非 \w
\S : 匹配非 \s
.: 匹配任意字符,但是不能匹配换行 ,如果加上 re.S 则匹配换行符
.*? : 非贪婪模式
.* : 贪婪模式
* : 匹配 0 - N 个*号前边的字符
+ : 匹配 1 - N 个+号前边的字符
? : 匹配 0 - 1 个?号前边的字符
[] : 任意字符,范围例如[a-zA-Z]所有字符都是原字符(无特殊含义)
[^] : 非 []内容里面的字符
{n} : 重复 N次
{m,n} : 重复 m 到 n 次
() : 分组
^ : 必须以规则开始
$ :必须以规则结束
注意:写规则的时候,前边尽量加r是好习惯
常用规则测试
import re
s = r'p112347598374958734pyt\\honpy.org0'
# 编译一个规则
# pattern = re.compile('\w\d')
# pattern = re.compile('\W\D')
# pattern = re.compile(r'\\+')
# pattern = re.compile('\.\.\.')
# pattern = re.compile('ww\d*pyt')
# pattern = re.compile('[a-zA-Z\d]+')
# pattern = re.compile('[^a-zA-Z\d]+')
# pattern = re.compile(r'\d{3,8}')
pattern = re.compile(r'(\d+)(.*)org')
# 如果匹配到则返回匹配到的内容,否则返回None
# res = pattern.search(s)
res = pattern.match(s)
if res is not None: # 匹配到 大
# 获取匹配内容
print(res.group(1))
else: # 小
print('无匹配')
正则 findall 应用
import re
html = """
<div id="d1" lsfffsdf>
<ul>
<li class="active" id=''>抽烟1</li>
<li>喝酒</li>
<li>烫头</li>
<li>洗脚2</li>
</ul>
</div>
<div id="d2" dlkdjlkdjfl><div><span>乱七八糟</span></div></div>
<ul>
<li class="active" id=''>抽烟1</li>
<li>喝酒2222</li>
<li>烫头222</li>
<li>洗脚2222</li>
</ul>
</div>
<table>
<tr>
<td></td>
</tr>
</table>
"""
# findall 把分组内容提取出来
# pat = re.compile(r'<li.*>(.*)(\d)</li>')
# res = pat.findall(html)
# print(res)
# pat = re.compile(r'<div id="d2">.*</div>',re.S)
# res = pat.findall(html)
# print(res)
# <div id="d2" dlkdjlkdjfl><div><span>乱七八糟</span></div></div>
pat = re.compile(r'<div.+?</div>')
res = pat.findall(html)
print(res)
补充
匹配中文
在某些情况下,我们想匹配文本中的汉字,有一点需要注意的是,中文的 unicode 编码范围 主要在 [u4e00-u9fa5],这里说主要是因为这个范围并不完整,比如没有包括全角(中文)标点,不过,在大部分情况下,应该是够用的。
假设现在想把字符串 title = u'你好,hello,世界' 中的中文提取出来,可以这么做:
import re
title = u'你好,hello,世界'
pattern = re.compile(ur'[\u4e00-\u9fa5]+')
result = pattern.findall(title)
print (result)
注意到,我们在正则表达式前面加上了两个前缀 ur,其中 r 表示使用原始字符串,u 表示是 unicode 字符串。
执行结果:
[u'\u4f60\u597d', u'\u4e16\u754c']
注意:贪婪模式与非贪婪模式
贪婪模式:在整个表达式匹配成功的前提下,尽可能多的匹配 ( * );
非贪婪模式:在整个表达式匹配成功的前提下,尽可能少的匹配 ( ? );
Python里数量词默认是贪婪的。
示例一 : 源字符串:abbbc
使用贪婪的数量词的正则表达式 ab* ,匹配结果: abbb。
* 决定了尽可能多匹配 b,所以a后面所有的 b 都出现了。
使用非贪婪的数量词的正则表达式ab*?,匹配结果: a。
即使前面有 *,但是 ? 决定了尽可能少匹配 b,所以没有 b。
示例二 : 源字符串:aa<div>test1</div>bb<div>test2</div>cc
使用贪婪的数量词的正则表达式:<div>.*</div>
匹配结果:<div>test1</div>bb<div>test2</div>
这里采用的是贪婪模式。在匹配到第一个“</div>”时已经可以使整个表达式匹配成功,但是由于采用的是贪婪模式,所以仍然要向右尝试匹配,查看是否还有更长的可以成功匹配的子串。匹配到第二个“</div>”后,向右再没有可以成功匹配的子串,匹配结束,匹配结果为“<div>test1</div>bb<div>test2</div>”
使用非贪婪的数量词的正则表达式:<div>.*?</div>
匹配结果:<div>test1</div>
正则表达式二采用的是非贪婪模式,在匹配到第一个“</div>”时使整个表达式匹配成功,由于采用的是非贪婪模式,所以结束匹配,不再向右尝试,匹配结果为“<div>test1</div>”。