25 正则表达式
1 正则表达式说明
A 正则表达式的作用和特点
给定一个正则表达式和另一个字符串,我们可以达到如下的目的:
1. 给定的字符串是否符合正则表达式的过滤逻辑(称作“匹配”);
2. 可以通过正则表达式,从字符串中获取我们想要的特定部分。
B 正则表达式的特点是:
1. 灵活性、逻辑性和功能性非常强;
2. 可以迅速地用极简单的方式达到字符串的复杂控制。
3. 对于刚接触的人来说,比较晦涩难懂。
C 使用场景:
1 如何判断一个字符串是手机号呢?
2 判断邮箱为163或者126的所有邮件地址
3 假如你在写一个爬虫,你得到了一个网页的HTML源码。其中有一段
<html><body><h1>hello world<h1></body></html>
你想要把这个hello world提取出来,但你这时如果只会python 的字符串处理,那么第一反应可能是
s = "<html><body><h1>hello world</h1></body></html>"
start_index = s.find('<h1>')
2 正则说明
python re模块:
\A:表示从字符串的开始处匹配
\Z:表示从字符串的结束处匹配,如果存在换行,只匹配到换行前的结束字符串。
\b:匹配一个单词边界,也就是指单词和空格间的位置。例如, 'py\b' 可以匹配"python" 中的 'py',但不能匹配 "openpyxl" 中的 'py'。
\B:匹配非单词边界。 'py\b' 可以匹配"openpyxl" 中的 'py',但不能匹配"python" 中的 'py'。
\d:匹配任意数字,等价于 [0-9]。 digit
\D:匹配任意非数字字符,等价于 [^\d]。not digit ^在[]外面表示开头,在[]里面表示非
\s:匹配任意空白字符,等价于 [\t\n\r\f]。 space
\S:匹配任意非空白字符,等价于 [^\s]。
\w:匹配任意字母数字及下划线,等价于[a-zA-Z0-9_]。
\W:匹配任意非字母数字及下划线,等价于[^\w]
\\:匹配原义的反斜杠\。
‘.’用于匹配除换行符(\n)之外的所有字符。
‘^’用于匹配字符串的开始,即行首。
‘$’用于匹配字符串的末尾(末尾如果有换行符\n,就匹配\n前面的那个字符),即行尾。
定义正则验证次数:
‘*’ 用于将前面的模式匹配0次或多次(贪婪模式,即尽可能多的匹配) >=0
‘+’ 用于将前面的模式匹配1次或多次(贪婪模式) >=1
‘?’ 用于将前面的模式匹配0次或1次(贪婪模式) 0 ,1
'{m}' 用于验证将前面的模式匹配m次
'{m,}' 用于验证将前面的模式匹配m次或者多次 >=m
'{m,n}' 用于验证将前面的模式匹配大于等于m次并且小于等于n次
‘*?,+?,??’即上面三种特殊字符的非贪婪模式(尽可能少的匹配)。
‘{m,n}’用于将前面的模式匹配m次到n次(贪婪模式),即最小匹配m次,最大匹配n次。
‘{m,n}?’即上面‘{m,n}’的非贪婪版本。
‘\\’:'\'是转义字符,在特殊字符前面加上\,特殊字符就失去了其所代表的含义,比如\+就仅仅代表加号+本身。
‘[]’用于标示一组字符,如果^是第一个字符,则标示的是一个补集。比如[0-9]表示所有的数字,[^0-9]表示除了数字外的字符。
‘|’比如A|B用于匹配A或B。
‘(...)’用于匹配括号中的模式,可以在字符串中检索或匹配我们所需要的内容。
Python里数量词默认是贪婪的(在少数语言里也可能是默认非贪婪),总是尝试匹配尽可能多的字符;
非贪婪则相反,总是尝试匹配尽可能少的字符。
在"*","?","+","{m,n}"后面加上?,使贪婪变成非贪婪。
3 正则函数
import re
s = '娜扎热巴代斯佟丽娅'
result = re.match('佟丽娅', s)
print(result)
result = re.search('佟丽娅', s)
print(result)
print(result.span())
print(result.group())
print(result.groups())
s = '哈哈3u'
result = re.search('[0-9][a-z]', s)
print(result)
msg = 'abcd7yjkfd8hdf00'
result = re.search('[a-z][0-9][a-z]', msg)
print(result.group())
result = re.findall('[a-z][0-9][a-z]', msg)
print(result)
msg = 'a7aopa88akjgka7878a'
result = re.findall('[a-z][0-9]+[a-z]', msg)
print(result)
qq = '14944689962'
result = re.match('^[1-9][0-9]{4,10}$', qq)
print(result)
username = 'admin001'
result = re.search('^[a-zA-Z]\w{5,}$', username)
print(result)
4 正则分组
import re
n = '100'
'''
| 或者
() 分组 (163|126|qq) 一组
'''
result = re.match(r'[1-9]?\d?$|100$', n)
print(result)
email = '73877884@163.com'
result = re.match(r'\w{5,20}@(163|126|qq)\.(com|cn)$', email)
print(result)
phone = '15901018869'
result = re.match(r'1\d{9}[0-35-689]$', phone)
print(result.group())
phone = '010-12345678'
result = re.match(r'(\d{3}|\d{4})-(\d{8})$', phone)
print(result)
print(result.group())
print(result.group(1))
print(result.group(2))
msg = '<html><h1>abc</h1>'
msg1 = '<h1>hello</h1>'
result = re.match(r'<[0-9a-zA-Z]+>(.+)</[0-9a-zA-Z]+>', msg)
print(result)
print(result.group(1))
result = re.match(r'<([0-9a-zA-Z]+)>(.+)</\1>$', msg1)
print(result)
print(result.group(1))
print(result.group(2))
msg = '<html><h1>abc</h1></html>'
result = re.match(r'<([0-9a-zA-Z]+)><([0-9a-zA-Z]+)>(.+)</\2></\1>$',msg)
print(result)
print(result.group(1))
print(result.group(2))
print(result.group(3))
5 正则起名
import re
msg = '<html><h1>abc</h1></html>'
result = re.match(r'<(?P<name1>\w+)><(?P<name2>\w+)>(.+)</(?P=name2)></(?P=name1)>', msg)
print(result)
print(result.group(1))
print(result.group(2))
print(result.group(3))
'''
分组:() ---> result.group(1) 获取组中匹配内容
在分组的时候还可以结合 |
result = re.match(r'(\d{3}|\d{4})-(\d{8})$', phone)
print(result)
不需要引用分组的内容:
result = re.match(r'<[0-9a-zA-Z]+>(.+)</[0-9a-zA-Z]+>', msg)
print(result)
print(result.group(1))
引用分组匹配内容:
1.number \number 引用第number组的数据
msg = '<html><h1>abc</h1></html>'
result = re.match(r'<([0-9a-zA-Z]+)><([0-9a-zA-Z]+)>(.+)</\2></\1>$',msg)
print(result)
2.?P<名字>
msg = '<html><h1>abc</h1></html>'
result = re.match(r'<(?P<name1>\w+)><(?P<name2>\w+)>(.+)</(?P=name2)></(?P=name1)>',msg)
print(result)
print(result.group(1))
re模块:
match 从开头匹配一次
search 只匹配一次
findall 查找所有
sub(正则表达式,'新内容',string) 替换
split result = re.split(r'[,:]','java:99,python:95') 在字符串中搜索如果遇到:或者,就分割
将分割的内容都保存到列表中了
'''
def func(temp):
num = temp.group()
num1 = int(num) + 1
return str(num1)
result = re.sub(r'\d+', func, 'java:99,python:95')
print(result)
result = re.split(r'[,:]', 'java:99,python:95')
print(result)
6 正则实例
import re
import requests
path = '<img class="BDE_Image" src="http://imgsrc.baidu.com/forum/w%3D580/sign=30a7526a9282d158bb8259b9b00b19d5/704bde177f3e67092893917b35c79f3dfadc55f5.jpg" size="2227636" changedsize="true" width="560" height="840" style="cursor: url("http://tb2.bdstatic.com/tb/static-pb/img/cur_zin.cur"), pointer;">'
result = re.match(r'<img class="BDE_Image" src="(.*?)"', path)
image_path = result.group(1)
response = requests.get(image_path)
with open('aa.jpg', 'wb') as wstream:
wstream.write(response.content)