Python—第20天—正则表达式
正则表达式(regular expression)
它描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。
构造正则表达式的方法和创建数学表达式的方法一样。也就是用多种元字符与运算符可以将小的表达式结合在一起来创建更大的表达式。正则表达式的组件可以是单个的字符、字符集合、字符范围、字符间的选择或者所有这些组件的任意组合。
正则表达式是由普通字符(例如字符 a 到 z)以及特殊字符(称为"元字符")组成的文字模式。模式描述在搜索文本时要匹配的一个或多个字符串。正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。
正则表达式—>模式—>匹配字符串的模式—>复杂的匹配规则
关于正则表达式的相关知识,大家可以阅读一篇非常有名的博文叫《正则表达式30分钟入门教程》,读完这篇
文章后你就可以看懂下面的表格。
符号 | 解释 | 示例 | 说明 |
---|---|---|---|
. | 匹配任意字符 | b.t | 可以匹配bat / but / b#t / b1t等 |
\w | 匹配字母/数字/下划线 | b\wt | 可以匹配bat / b1t / b_t等 但不能匹配b#t |
\s | 匹配空白字符(包括\r、\n、\t等) | love\syou | 可以匹配love you |
\d | 匹配数字 | \d\d | 可以匹配01 / 23 / 99等 |
\b | 匹配单词的边界 | \bThe\b | |
^ | 匹配字符串的开始 | ^The | 可以匹配The开头的字符串 |
$ | 匹配字符串的结束 | .exe$ | 可以匹配.exe结尾的字符串 |
\W | 匹配非字母/数字/下划线 | b\Wt | 可以匹配b#t / b@t等 但不能匹配but / b1t / b_t等 |
\S | 匹配非空白字符 | love\Syou | 可以匹配love#you等 但不能匹配love you |
\D | 匹配非数字 | \d\D | 可以匹配9a / 3# / 0F等 |
\B | 匹配非单词边界 | \Bio\B | |
[] | 匹配来自字符集的任意单一字符 | [aeiou] | 可以匹配任一元音字母字符 |
[^] | 匹配不在字符集中的任意单一字符 | [^aeiou] | 可以匹配任一非元音字母字符 |
* | 匹配0次或多次 | \w* | |
+ | 匹配1次或多次 | \w+ | |
? | 匹配0次或1次 | \w? | |
{N} | 匹配N次 | \w{3} | |
{M,} | 匹配至少M次 | \w{3,} | |
{M,N} | 匹配至少M次至多N次 | \w{3,6} | |
| | 分支 | foo|bar | 可以匹配foo或者bar |
(?#) | 注释 | ||
(exp) | 匹配exp并捕获到自动命名的组中 | ||
(?<name>exp) | 匹配exp并捕获到名为name的组中 | ||
(?:exp) | 匹配exp但是不捕获匹配的文本 | ||
(?=exp) | 匹配exp前面的位置 | \b\w+(?=ing) | 可以匹配I’m dancing中的danc |
(?<=exp) | 匹配exp后面的位置 | (?<=\bdanc)\w+\b | 可以匹配I love dancing and reading中的第一个ing |
(?!exp) | 匹配后面不是exp的位置 | ||
(?<!exp) | 匹配前面不是exp的位置 | ||
*? | 重复任意次,但尽可能少重复 | a.*b a.*?b | 将正则表达式应用于aabab,前者会匹配整个字符串aabab,后者会匹配aab和ab两个字符串 |
+? | 重复1次或多次,但尽可能少重复 | ||
?? | 重复0次或1次,但尽可能少重复 | ||
{M,N}? | 重复M到N次,但尽可能少重复 | ||
{M,}? | 重复M次以上,但尽可能少重复 |
Python使用正则表达式的两种方法:
- 不创建正则表达式对象,直接调用函数进行匹配操作
- match
- fullmatch
- 创建正则表达式对象(Pattern),通过对象发消息实现匹配操作
- compile
使用match函数
验证用户名是否有效
import re
username = input('请输入用户名;')
matcher = re.match(r'^\w{6,20}$', username)
if matcher is None:
print('用户不合法')
else:
# 打印输入的用户名
print(matcher.group())
验证QQ号是否有效
import re
qq = input('请输入QQ号:')
matcher = re.match(r'^[1-9]\d{4,}$', qq)
if matcher is None:
print('QQ不合法')
else:
print(matcher)
print(matcher.group())
验证手机号号是否有效
import re
tel = input('请输入手机号:')
matcher = re.match(r'1[3-9]\d{9}', tel)
if matcher is None:
print('手机号不合法')
else:
print(matcher)
print(matcher.group())
使用compile函数
验证用户名是否有效
import re
username = input('请输入用户名;')
# 通过compile编译正则表达式创建Pattern对象
username_pattern = re.compile(r'^\w{6,20}$')
# 通过给Pattern对象发消息实现匹配检查
matcher = username_pattern.match(username)
if matcher is None:
print('用户不合法')
else:
print(matcher.group())
从一段文字中提取出国内手机号码。
import re
content = """报警电话:110,我们班是Python-2105班,
我的QQ号是957658,我的手机号是13811223344,谢谢! """
matcher = re.search(r'1[3-9]\d{9}', content)
if matcher is None:
print('没有找到手机号')
else:
print(matcher.group())
提取所有数字
# 方法一:
pattern = re.compile(r'\d+')
matcher = pattern.search(content)
while matcher:
print(matcher.group())
matcher = pattern.search(content, matcher.end())
# 方法二:
pattern = re.compile(r'\d+')
results = pattern.findall(content)
print(results)
for result in results:
print(result)
# 方法三:
results = re.findall(r'\d+', content)
print(results)
for result in results:
print(result)
match - 匹配 - 从头开始进行匹配 —> Match对象 —> group()
search - 搜索 - 从任意位置匹配 —> Match对象 —> group()
findall - 从字符串中找出所有和正则表达式匹配的内容 —> list[str]
正则表达式捕获组
从网页上获取新闻的标题和链接
import requests
import re
# 链接的正则表达式匹配
pattern1 = re.compile(r'href="http.+?"')
# 获取网页
resp = requests.get('http://www.sohu.com/')
content = resp.text
# 匹配网页的文本
matcher = pattern1.search(content)
while matcher:
print(matcher.group()[6:-1])
matcher = pattern1.search(content, matcher.end())
# 标题的正则表达式匹配
pattern2 = re.compile(r'title=".+?"')
title_list = pattern2.findall(content)
for title in title_list:
print(title[7:-1])
# 网页的新闻和标题分开获取
如下这种方法更好:
import re
import requests
# 网页新闻链接和标题的正则表达式匹配
pattern1 = re.compile(r'<a\s.*?href="(.+?)".*?title="(.+?)".*?>')
resp = requests.get('https://www.sohu.com/')
content = resp.text
results = pattern1.findall(content)
for href, title in results:
print(title)
# 网页中有些链接没有https://www.sohu.com/我们需做判断,有直接输出,没有加上在输出
# startswith函数查看开头有没有对应的
if not href.startswith('https://www.sohu.com/'):
href = 'https://www.sohu.com/' + href
print(href)
不良内容过滤
import re
content = '张三是一个傻逼沙雕, FuCk you!!!'
# 方法一:
# pattern = re.compile(r'[傻沙煞][逼笔雕鄙]|[张三]|fuck|shit', flags=re.IGNORECASE)
# modified_content = pattern.sub('*', content)
# 方法二:
modified_content = re.sub(r'[傻沙煞][逼笔雕鄙]|[张三]|fuck|shit', '*', content, flags=re.I)
print(modified_content)
用正则表达式拆分字符串
import re
poem = '窗前明月光,疑是地上霜。举头望明月,低头思故乡。'
# sentences_list = re.split(r'[,。, .]', poem)
pattern = re.compile(r'[,。, .]')
sentences_list = pattern.split(poem)
# 去掉列表最后的空字符串
sentences_list = [sentence for sentence in sentences_list if sentence]
for sentence in sentences_list:
print(sentence)
- 关于正则表达式的相关知识,大家可以阅读一篇非常有名的博文叫《正则表达式30分钟入门教程》