在Python中需要通过正则表达式对字符串进行匹配的时候,可以使用一个模块,名字为re
#coding=utf-8
# 导入re模块
import re
# 使用match方法进行匹配操作
result = re.match(正则表达式,要匹配的字符串)
# 如果上一步匹配到数据的话,可以使用group方法来提取数据
result.group()
例如要从“hello world” 中查找hello, 可以这样处理:
# encoding=utf-8
import re
def main():
result = re.match("hello", "hello world")
print(result.group()) # hello
if __name__ == "__main__":
main()
re.match() 能够匹配出以xxx开头的字符串
字符 | 功能 |
---|---|
. | 匹配任意1个字符(除了\n) |
[] | 匹配[]中列举的字符 |
\d | 匹配数字,即0-9 |
\D | 匹配非数字,即不是数字 |
\s | 匹配空白,即空格,tab键 |
\S | 匹配非空白 |
\w | 匹配单词字符,即a-z,A-Z,0-9,_ |
# encoding=utf-8
import re
def main():
ret = re.match(".", "M")
print(ret.group())
ret = re.match("t.o", "toooo")
print(ret.group())
ret = re.match("t.o", "two")
print(ret.group())
if __name__ == "__main__":
main()
输出结果:
M
too
two
# encoding=utf-8
import re
def main():
# 如果hello的首字符小写,那么正则表达式需要小写的h
ret = re.match("h", "hello Python")
print(ret.group()) # 结果:h
# 如果hello的首字符大写,那么正则表达式需要大写的H
ret = re.match("H", "Hello Python")
print(ret.group()) # 结果:H
# 大小写h都可以的情况
ret = re.match("[hH]", "hello Python")
print(ret.group()) # 结果:h
ret = re.match("[hH]", "Hello Python")
print(ret.group()) # 结果:H
ret = re.match("[hH]ello Python", "Hello Python") # 结果:Hello Python
print(ret.group())
# 匹配0到9的第一种写法
ret = re.match("[0123456789]hello python", "7hello python") # 结果:7hello python
print(ret.group())
# 匹配0到9第二种写法
ret = re.match("[0-9]Hello Python", "7Hello Python") # 结果:7hello python
print(ret.group())
ret = re.match("[0-35-9]Hello Python", "7Hello Python") # 结果:7hello python
print(ret.group())
# 下面这个正则不能够匹配到数字4,因此ret为None
ret = re.match("[0-35-9]Hello Python", "4Hello Python")
# print(ret.group()) 会报错
if __name__ == "__main__":
main()
# encoding=utf-8
import re
def main():
ret = re.match("aa\dbb", "aa2bb")
print(ret.group()) # 结果:aa2bb
if __name__ == "__main__":
main()
# encoding=utf-8
import re
def main():
ret = re.match("12\D34", "12a34")
print(ret.group()) # 结果:12a34
if __name__ == "__main__":
main()
# encoding=utf-8
import re
def main():
ret = re.match("12\s34", "12 34")
print(ret.group()) # 结果:12 34
if __name__ == "__main__":
main()
# encoding=utf-8
import re
def main():
ret = re.match("\S34", "a34")
print(ret.group()) # 结果:a34
if __name__ == "__main__":
main()
# encoding=utf-8
import re
def main():
ret = re.match("\w", "world 123")
print(ret.group()) # 结果:w
if __name__ == "__main__":
main()
# encoding=utf-8
import re
def main():
ret = re.match("\W", "$hello")
print(ret.group()) # 结果:$
if __name__ == "__main__":
main()
匹配多个字符的相关格式
字符 | 功能 |
---|---|
* | 匹配前一个字符,出现0次或者无限次,即可有可无 |
+ | 匹配前一个字符出现1次或者无限次,即至少有一次 |
? | 匹配前一个字符出现1次或者0次,即最多有一次 |
{m} | 匹配前一个字符出现m次 |
{m,n} | 匹配前一个字符出现从m到n次 |
# encoding=utf-8
import re
def main():
# 匹配大写字母开头,后面有0个或多个小写字母
ret = re.match("[A-Z][a-z]*", "Hello World")
print(ret.group()) # 结果:Hello
if __name__ == "__main__":
main()
# coding=utf-8
import re
names = ["name1", "_name", "2_name", "__name__"]
for name in names:
# 匹配字母或者下划线开头的次数出现1次或多次,后面出现0次或多次个字符
ret = re.match("[a-zA-Z_]+[\w]*", name)
if ret:
print("变量名 %s 符合要求" % ret.group())
else:
print("变量名 %s 非法" % name)
输出结果:
变量名 name1 符合要求
变量名 _name 符合要求
变量名 2_name 非法
变量名 __name__ 符合要求
# coding=utf-8
import re
def main():
# 匹配出,0到99之间的数字
ret = re.match("[1-9]?[0-9]", "75")
print(ret.group()) # 75
ret = re.match("[1-9]?\d", "33")
print(ret.group()) # 33
ret = re.match("[1-9]?\d", "09")
print(ret.group()) # 0
if __name__ == '__main__':
main()
## (4) {m},次数限定匹配符
```python
# coding=utf-8
import re
# 匹配出,8到20位的密码,可以是大小写英文字母、数字、下划线
ret = re.match("[a-zA-Z0-9_]{6}", "12a3g45678")
print(ret.group()) # 12a3g4
ret = re.match("[a-zA-Z0-9_]{8,20}", "1ad12f23s34455ff66")
print(ret.group()) # 小于8个字符会报错, 1ad12f23s34455ff66
# 上面的[a-zA-Z0-9_]其实也可以用\w来替代
字符 | 功能 |
---|---|
^ | 匹配字符串开头 |
$ | 匹配字符串结尾 |
(1) 匹配数字开头的字符串
# coding=utf-8
import re
ret = re.match("^\d*", "1232456aaaaa")
print(ret.group()) # 结果:1232456
(2) 匹配@163.com结尾的字符串
# coding=utf-8
import re
email_list = ["[email protected]", "[email protected]", "[email protected]"]
for email in email_list:
ret = re.match("\w*@163.com$", email)
if ret:
print("匹配成功的是:%s" % ret.group())
else:
print("匹配失败的是:%s" % email)
输出结果:
匹配成功的是:xiaoWang@163.com
匹配失败的是:xiaoWang@163.comheihei
匹配失败的是:.com.xiaowang@qq.com
字符 | 功能 |
---|---|
| | 匹配左右任意一个表达式 |
(ab) | 将括号中字符作为一个分组 |
\num | 引用分组匹配到的字符串 |
(?p) | 分组起别名 |
(?P=name) | 引用别名name分组匹配的字符串 |
# coding=utf-8
import re
ret = re.match("[1-9]?\d$|100", "100")
print(ret.group()) # 100
ret = re.match("[1-9]?\d$|100", "20")
print(ret.group()) # 20
# coding=utf-8
import re
email_list = ["[email protected]", "[email protected]", "[email protected]"]
for email in email_list:
ret = re.match("\w+@(163|126|qq)\.com$", email)
print(ret.group())
输出结果:
abc@126.com
hello@163.com
xxx@qq.com
例如要匹配形如出hh格式的字符串, 你可能会想到下面的方式:
# coding=utf-8
import re
# 能够完成对正确的字符串的匹配
ret = re.match("<[a-zA-Z]+>\w*[a-zA-Z]+>", "hh")
print(ret.group())
输出结果:
<html>hh</html>
但是这种还会匹配出错误的结果,例如这种hh,按理说后面的<>要和前面的内容一样,这个时候就可以引用分组,引用分组的格式是:\分组的数字,同时还需要在正则表达式前加上r,分组的部分需要用()括起来,而\1对于的就是分组1,以此类推,例如:
# coding=utf-8
import re
# 能够完成对正确的字符串的匹配
ret = re.match(r"<([a-zA-Z]+)>\w*\1>", "hh")
print(ret.group())
以匹配出
为例www.163.com
# coding=utf-8
import re
# 能够完成对正确的字符串的匹配
ret = re.match(r"<(?P\w+)><(?P\w+)>.*(?P=group2)>(?P=group1)>" ,
"www.163.com
")
print(ret.group())
注意:(?P)和(?P=name)中的字母p大写
# coding=utf-8
import re
# 匹配出文章阅读的次数
# 匹配出文章阅读的次数
ret = re.search(r"\d+", "阅读次数为 9999 点赞数 10")
print(ret.group()) # 9999
# coding=utf-8
import re
# 统计出python、c、c++相应文章阅读的次数
ret = re.findall(r"\d+", "python = 9999, c = 7890, c++ = 12345")
print(ret) # ['9999', '7890', '12345']
# coding=utf-8
import re
# 将python = 997中的977替换成100
ret = re.sub(r"\d+", '100', "python = 997")
print(ret) # 结果:python = 100
例如要提取网页的内容,非标签字符可以这样处理:
# coding=utf-8
import re
test_str = """
岗位职责:
完成推荐算法、数据统计、接口、后台等服务器端相关工作
必备要求:
良好的自我驱动力和职业素养,工作积极主动、结果导向
技术要求:
1、一年以上 Python 开发经验,掌握面向对象分析和设计,了解设计模式
2、掌握HTTP协议,熟悉MVC、MVVM等概念以及相关WEB开发框架
3、掌握关系数据库开发设计,掌握 SQL,熟练使用 MySQL/PostgreSQL 中的一种
4、掌握NoSQL、MQ,熟练使用对应技术解决方案
5、熟悉 Javascript/CSS/HTML5,JQuery、React、Vue.js
加分项:
大数据,数理统计,机器学习,sklearn,高性能,大并发。
"""
ret = re.sub(r"<[^>]*>| |", "", test_str)
print(ret)
思路很简单就是将标签<>或者>替换成空白字符即可,至于<>的内容可以用[^>]*来表示。
# coding=utf-8
import re
# 如果想按:分割字符串,可以这样
ret = re.split(r":", "info:xiaoZhang 33 shandong")
print(ret)
# 如果想按:或者空格符分割字符串,可以这样
ret = re.split(r":| ", "info:xiaoZhang 33 shandong")
# 上面这句还可以改成:ret = re.split(r":|\s", "info:xiaoZhang 33 shandong")
print(ret)
输出结果:
['info', 'xiaoZhang 33 shandong']
['info', 'xiaoZhang', '33', 'shandong']
Python里数量词默认是贪婪的也就是尝试匹配尽可能多的字符;
而非贪婪则相反,总是尝试匹配尽可能少的字符。
在"*“,”?“,”+“,”{m,n}"后面加上?,使贪婪变成非贪婪。
# coding=utf-8
import re
# 贪婪模式(默认),尽可能匹配的多点
s = "This is a number 234-235-22-423"
r = re.match(".+(\d+-\d+-\d+-\d+)", s)
print(r.group()) # This is a number 234-235-22-423
print(r.group(1)) # 4-235-22-423, 这里group(1) 可以获取第一个()内的内容
# 非贪婪模式,尽可能匹配的少点
r = re.match(".+?(\d+-\d+-\d+-\d+)", s)
print(r.group()) # This is a number 234-235-22-423
print(r.group(1)) # 234-235-22-423
输出结果:
This is a number 234-235-22-423
4-235-22-423
This is a number 234-235-22-423
234-235-22-423
group方法可以传入分组的编号,这样就可以取对应分组的内容了,如果不传则取所有内容
再入可以配合findall或者search来提取特定字符串,例如提取网页中的url
# coding=utf-8
import re
test_str = """
"
"""
# 如何提取url
ret = re.findall(r"https://.*?\.jpg", test_str)
print(ret)
输出结果:
['https://rpic.douyucdn.cn/appCovers/2016/11/13/1213973_201611131917_small.jpg', 'https://rpic.douyucdn.cn/appCovers/2016/11/13/1213973_201611131917_small.jpg']
Python中字符串前面加上 r 表示原生字符串
与大多数编程语言相同,正则表达式里使用`\`作为转义字符,这就可能造成反斜杠困扰。假如你需要匹配文本中的字符`\`,那么使用编程语言表示的正则表达式里将需要2个反斜杠,即`\\`. 而Python里的原生字符串很好地解决了这个问题,有了原生字符串,你再也不用担心是不是漏写了反斜杠,写出来的表达式也更直观。
例如:
# coding=utf-8
import re
# 没有使用原生字符串的使用
test_str = "c:\\a\\b\\c"
ret = re.match("c:\\\\a", test_str).group()
print(ret) # c:\a
# 使用了原生字符串的使用
test_str = r"c:\a\b\c"
# 正则表达式里面只需要对\进行一次转义即可
ret = re.match(r"c:\\a", test_str).group()
print(ret) # c:\a