友情提示:将下文中代码拷贝到JupyterNotebook中直接执行即可,部分代码需要连续执行。
正则表达式 | 描述 | 正则表达式 | 描述 |
---|---|---|---|
. | 匹配任意字符,除了换行符 | {n,m} | 重复n到m次 |
\w | 匹配字母数字及下划线 | \W | 匹配非字母数字及下划线 |
\s | 匹配任意空白字符 | \S | 匹配任意非空字符 |
\d | 匹配任意数字,等价于 [0-9] | \D | 匹配任意非数字 |
\b | 匹配一个单词边界,也就是指单词和空格间的位置 | \B | 匹配非单词边界 |
^ | 匹配字符串的开头 | [^...] | 不在[]中的字符:[^abc] 匹配除了a,b,c之外的字符 |
$ | 匹配字符串的末尾 | [0-9] | 匹配任何数字。类似于 [0123456789] |
* | 重复零次或更多次 | [a-z] | 匹配任何小写字母 |
+ | 重复一次或更多次 | [A-Z] | 匹配任何大写字母 |
? | 重复零次或一次 | [a-zA-Z0-9] | 匹配任何字母及数字 |
{n} | 重复n次 | [^aeiou] | 除了aeiou字母以外的所有字符 |
{n,} | 重复n次或更多次 | [^0-9] | 匹配除了数字外的字符 |
re.match 尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match() 就返回 none。
函数语法:
re.match(pattern, string, flags=0)
参数 | 描述 |
---|---|
pattern | 匹配的正则表达式 |
string | 要匹配的字符串 |
flags | 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等 |
修饰符 | 描述 |
---|---|
re.I | 使匹配对大小写不敏感 |
re.L | 做本地化识别(locale-aware)匹配 |
re.M | 多行匹配,影响 ^ 和 $ |
re.S | 使 . 匹配包括换行在内的所有字符 |
re.U | 根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B. |
re.X | 该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。 |
如下例,在起始位置匹配成功,返回匹配对象。
import re
result = re.match(r'www','www.baidu.com')
print(result)
不在起始位置匹配,匹配失败,返回None
import re
result = re.match(r'com','www.baidu.com')
print(result)
None
我们可以使用 group(num) 或 groups() 匹配对象函数来获取匹配表达式。
匹配对象方法 | 描述 |
---|---|
group(默认num=0) | 匹配的整个表达式的字符串,group() 可以一次输入多个组号,它将返回一个所对应值的元组 |
groups() | 返回一个包含所有小组字符串的元组,从 1 到 所含的小组号 |
import re
string='Cats are smarter than dogs'
result = re.match(r'(.*) are (.*?) .*',string)
print(result)
print(result.group())
print(result.group(1))
print(result.group(2))
print(result.groups())
Cats are smarter than dogs
Cats
smarter
('Cats', 'smarter')
re.search 扫描整个字符串并返回第一个成功的匹配。函数语法:
re.search(pattern, string, flags=0)
参数 | 描述 |
---|---|
pattern | 匹配的正则表达式 |
string | 要匹配的字符串 |
flags | 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等 |
如下例,匹配一次或更多次数字。
import re
result = re.search(r'\d+','阅读次数 9999次')
print(result)
print(result != None)
True
同样我们也可以使用 group(num) 或 groups() 匹配对象函数来获取匹配表达式。
匹配对象方法 | 描述 |
---|---|
group(默认num=0) | 匹配的整个表达式的字符串,group() 可以一次输入多个组号,它将返回一个所对应值的元组 |
groups() | 返回一个包含所有小组字符串的元组,从 1 到 所含的小组号 |
import re
mo = re.search(r'(\d\d\d)-(\d\d\d-\d\d\d\d)','My number is 415-555-4242.')
print(mo)
print(mo.group())
print(mo.group(1))
print(mo.group(2))
print(mo.groups())
415-555-4242
415
555-4242
('415', '555-4242')
re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;
而re.search匹配整个字符串,直到找到一个匹配。
如下例:
import re
string = "Cats are smarter than dogs"
#match
matchObj = re.match( r'dogs', string, re.M|re.I)
if matchObj:
print("match --> matchObj.group() : ", matchObj.group())
else:
print("No match!!")
#search
matchObj = re.search( r'dogs', string, re.M|re.I)
if matchObj:
print("match --> matchObj.group() : ", matchObj.group())
else:
print("No match!!")
No match!!
match --> matchObj.group() : dogs
compile 函数用于编译正则表达式,生成一个正则表达式( Pattern )对象,供 match() 和 search() 这两个函数使用。函数语法:
re.compile(pattern[, flags])
import re
Regex = re.compile(r'\baaa')
result = Regex.search('aaaaaabbb')
print(result)
import re
Regex = re.compile(r'\(\d\)')
test = Regex.search('sss (5) 2222')
print(test.group())
(5)
"|"字符称为管道。您可以在任何需要匹配多个表达式之一的地方使用它。
第一次出现的匹配文本将作为匹配对象返回。
import re
heroRegex = re.compile (r'Batman|Tina Fey')
mo1 = heroRegex.search('Batman and Tina Fey')
print("1:"+mo1.group())# first occurrence is Batman
mo2 = heroRegex.search('Tina Fey and Batman')
print("2:"+mo2.group())# first occurrence is Tina Fey
1:Batman
2:Tina Fey
import re
batRegex = re.compile(r'Bat(man|mobile|copter|bat)')
mo = batRegex.search('Batmobile lost a wheel')
print(mo)
print("2:"+mo.group(0))#Bat(mobile...
print("3:"+mo.group(1))#(mobile...)
2:Batmobile
3:mobile
import re
batRegex = re.compile(r'Bat(wo)?man')
mo1 = batRegex.search('The Adventures of Batman')#无 wo
print(mo1.group())
mo2 = batRegex.search('The Adventures of Batwoman')#有 wo
print(mo2.group())
Batman
Batwoman
import re
batRegex = re.compile(r'Bat(wo)*man')
mo1 = batRegex.search('The Adventures of Batman')#无或者更多次
mo1.group()
'Batman'
import re
batRegex = re.compile(r'Bat(wo)+man')
mo1 = batRegex.search('The Adventures of Batwoman')#1次
print(mo1.group())
mo2 = batRegex.search('The Adventures of Batwowowowoman')#多次
print(mo2.group())
mo3 = batRegex.search('The Adventures of Batman')
print(mo3 == None)
Batwoman
Batwowowowoman
True
import re
haRegex = re.compile(r'(Ha){3}')
mo1 = haRegex.search('HaHaHatttttt')
mo1.group()
'HaHaHa'
贪婪模式
import re
haRegex = re.compile(r'(Ha){3,6}')
mo1 = haRegex.search('HaHaHaHaHaHaHaHaHaHa')#贪婪模式,即选择6次
mo1.group()
'HaHaHaHaHaHa'
满足最低条件
import re
greedyHaRegex = re.compile(r'(Ha){3,5}')
mo1 = greedyHaRegex.search('HaHaHaHaHaHaHa')#贪婪模式,即选择5次
print(mo1.group())
nongreedyHaRegex = re.compile(r'(Ha){3,5}?')#满足最低条件,即选择3次
mo2 = nongreedyHaRegex.search('HaHaHaHaHa')
print(mo2.group())
HaHaHaHaHa
HaHaHa
在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果有多个匹配模式,则返回元组列表,如果没有找到匹配的,则返回空列表。
即match 和 search 是匹配一次 而findall 匹配所有。findall函数语法为:
findall(string[, pos[, endpos]])
参数:
- string : 待匹配的字符串。
- pos : 可选参数,指定字符串的起始位置,默认为 0。
- endpos : 可选参数,指定字符串的结束位置,默认为字符串的长度。
无分组情况
import re
phoneNumRegex = re.compile(r'\d\d\d-\d\d\d-\d\d\d\d') #无分组情况
phoneNumRegex.findall('Cell: 415-555-9999 Work: 212-555-0000')
['415-555-9999', '212-555-0000']
有分组情况,返回tuple元组
import re
phoneNumRegex = re.compile(r'(\d\d\d)-(\d\d\d)-(\d\d\d\d)') #有分组情况
phoneNumRegex.findall('Cell: 415-555-9999 Work: 212-555-0000')#返回一个tuple
[('415', '555', '9999'), ('212', '555', '0000')]
指定开始位置和结束位置
import re
numRegex = re.compile(r'\d+')#查找数字
numRegex.findall("6baidu888google12345",0,17)#指定0到17的位置种查询
['6', '888', '12']
[ ]表示匹配中括号内相应内容,如[0-9]即匹配所有数字,[a-z]即匹配所有小写字母,[a-zA-Z0-9]即匹配所有数字字母,[^0-9]即匹配所有非数字
import re
vowelRegex = re.compile(r'ba|[aeiouAEIOU]')#匹配元音
vowelRegex.findall('RoboCop eats baby fOOd.')
['o', 'o', 'o', 'e', 'a', 'ba', 'O', 'O']
import re
vowelRegex = re.compile(r'[^aeiouAEIOU]')#匹配非元音
vowelRegex.findall('RoboCop eats baby fOOd.')
['R', 'b', 'C', 'p', ' ', 't', 's', ' ', 'b', 'b', 'y', ' ', 'f', 'd', '.']
import re
vowelRegex = re.compile(r'[0-5.]')#这里匹配的是"0-5以及."
vowelRegex.findall('123450. BABY FOOD.')
['1', '2', '3', '4', '5', '0', '.', '.']
import re
atRegex = re.compile(r'.at')#这里的"."代表匹配任意字符
atRegex.findall('The cat in the hat ssate on the flat mat.')
['cat', 'hat', 'sat', 'lat', 'mat']
Python 的 re 模块提供了re.sub用于替换字符串中的匹配项。函数语法:
re.sub(pattern, repl, string, count=0, flags=0)
参数:
- pattern : 正则中的模式字符串。
- repl : 替换的字符串,也可为一个函数。
- string : 要被查找替换的原始字符串。
- count : 模式匹配后替换的最大次数,默认 0 表示替换所有的匹配。
如下例,移除电话号码中的 “-” 字符串,即用 “” 替换 “-”
import re
tel = re.sub(r"\D","","021-8678-0543")
print(tel)
02186780543
re.sub常用来作为某个单词或者姓名的替换,如下例,将Agent后面的姓名替换为新的姓名
import re
namesRegex = re.compile(r'Agent \w+')
namesRegex.sub('Lucifer', 'Agent Alice gave the secret documents to Agent Bob.')
'Lucifer gave the secret documents to Lucifer.'
满足最低条件与贪婪模式
import re
nongreedyRegex = re.compile(r'{.*?}')#这里的{}就代表大括号,有?则是满足最低条件即可
mo = nongreedyRegex.search('{To serve man} for dinner}')
print("满足最低条件:",mo.group())
greedyRegex = re.compile(r'<.*>')#没有?号,则是贪婪模式
mo = greedyRegex.search(' for dinner.>' )
print("贪婪模式:",mo.group())
满足最低条件: {To serve man}
贪婪模式: for dinner.>
"."表示任意字符,但不包括换行符\n
import re
noNewlineRegex = re.compile('.*')#这里的"."表示任意字符不包括换行符
noNewlineRegex.search('Serve the public trust.\nProtect the innocent.\nUphold the law.').group()
'Serve the public trust.'
通过修饰符re.S(等同于re.DOTALL),使 . 匹配包括换行在内的所有字符
import re
newlineRegex = re.compile('.*', re.S)#re.S等同于re.DOTALL include all character
newlineRegex.search('Serve the public trust.\nProtect the innocent.\nUphold the law.').group()
'Serve the public trust.\nProtect the innocent.\nUphold the law.'
通过修饰符re.I使匹配大小写不敏感
import re
robocop = re.compile(r'robocop',re.I)
print(robocop.search('RoboCop is part man, part machine, all cop.').group())
print(robocop.search('ROBOCOP protects the innocent.').group())
print(robocop.search('Al, why does your programming book talk about robocop so much?').group())
RoboCop
ROBOCOP
robocop
exp1是一个句子,exp2是一个句子
先行断言:
后行断言
如下例,查找后面是标签的任意字符串
import re
xianRegex = re.compile(r".+(?=)")
xian = fontRegex.search("阅读数:641")
print(xian.group())
阅读数:641
查找前面是是标签的任意字符串
import re
houRegex = re.compile(r"(?<=)
hou = houRegex.search("阅读数:641")
print(hou.group())
class="read-count">阅读数:641
您的代码:
您的代码:
Hello somebody ,welcome to my home ,I’m waiting for you.
您的代码:
输入日期格式有可能如下:
20210601
2021-06-01
2021/06/01
2021/6/1
2021年6月1日
2021年06月01日
您的代码:
import requests
import json
def mobilecity(mobile:"手机号")->"输出归属地等信息":
url = 'https://api.oioweb.cn/api/common/teladress'#API接口地址
params = {}
params['mobile'] = mobile
headers={'Content-Type':'application/json;charset=UTF-8'}
response = requests.post(url=url,params=params,headers=headers)#使用POST请求
mobileinfo = json.loads(response.text)
return mobileinfo["result"]
mobilecity("13988888888")
{‘name’: ‘移动全球通卡’,
‘postCode’: ‘674100’,
‘prov’: ‘云南’,
‘city’: ‘丽江市’,
‘cityCode’: ‘530700’,
‘num’: 1398888,
‘provCode’: ‘530000’,
‘areaCode’: ‘0888’,
‘type’: 1}
import requests
from bs4 import BeautifulSoup
import jieba
import wordcloud
from matplotlib import pyplot as plt
#爬取网页数据
reponse = requests.get("http://www.gov.cn/zhengce/2021-02/21/content_5588098.htm")
reponse.encoding='utf-8'
#整理
soup = BeautifulSoup(reponse.text,"xml")
result = soup.find_all("p")
text = [c.text for c in result]
#分词
ci = "".join(text)
fenci = list(jieba.cut(ci))
ciyun = [word for word in fenci if len(word)>1 and word not in ["\r\n"]]
#生成词云图片并输出
wc = wordcloud.WordCloud(width=1200, font_path='msyh.ttc',height=800,scale=3,background_color='white')
wc.generate(' '.join(ciyun))
plt.imshow(wc)