Python正则表达式


1 正则表达式介绍

正则表达式 :一组由字母和符号组成的特殊文本,可以帮助我们从某个复杂的字符串中,提取出满足我们要求的特殊文本。

实际开发过程中经常会有查找符合某些复杂规则的字符串的需要,比如:邮箱、图片地址、手机号码等,这时候想匹配或者查找符合某些规则的字符串就可以使用正则表达式了。

2 re模块介绍

本文通过python中正则进行举例测试。首先python中使用正则表达式需要导入模块re。

注:re.match() 根据正则表达式从头开始匹配字符串数据,如果如果开头没有匹配上,则会报错。下面案例都会使用match进行匹配,方便讲解。

2.1 re模块的介绍

在Python中需要通过正则表达式对字符串进行匹配的时候,可以使用一个 re 模块。

# 导入re模块
import re
# 使用match方法进行匹配操作
result = re.match(正则表达式,要匹配的字符串)
# 如果上一步匹配到数据的话,可以使用group方法来提取数据
result.group()

2.2 re模块的使用

import re
# 使用match方法进行匹配操作
result = re.match("csdn","csdn.net")
# 获取匹配结果
info = result.group()
print(info)
# csdn

正则表达式之所以这么强大,是因为拥有很多专用的操作符(又称“元字符”)、特殊字符和修饰符。

为了更加方便记忆和学习正则表达式,我将这些分成了匹配单个字符、匹配多个字符、匹配开头结尾、匹配分组来分别讲解。

3 匹配单个字符

代码功能
.匹配任意1个字符(除了换行符\n)
[ ]匹配[ ]中列举的字符
\d匹配数字,即0-9
\D匹配非数字,即不是数字
\s匹配空白,即 空格,tab键
\S匹配非空白
\w匹配非特殊字符,即a-z、A-Z、0-9、_、汉字
\W匹配特殊字符,即非字母、非数字、非汉字

3.1 示例1: .

import re
# . 匹配任意1个字符(除了\n)
# 1. 正则表达式
# 2. 要匹配的字符串
# match_obj返回匹配对象
ret = re.match(".","M")
print(ret.group())
ret = re.match("t.o","too")
print(ret.group())
ret = re.match("t.o","two")
print(ret.group())
match_obj = re.match("t.o", "t\no")
if match_obj:
# 获取匹配结果
result = match_obj.group()
print(result)
else:
# 匹配失败match_obj是一个None
print("匹配失败")

运行结果:

M
too
two
匹配失败

3.2 示例2:[]

import re
# 1. 正则表达式
# 2. 要匹配的字符串
# match_obj返回匹配对象
# [ ] 匹配[ ]中列举的字符
# 如果hello的首字符小写,那么正则表达式需要小写的h
ret = re.match("h","hello Python")
print(ret.group())
# 如果hello的首字符大写,那么正则表达式需要大写的H
ret = re.match("H","Hello Python")
print(ret.group())
match_obj = re.match("葫芦娃[12]", "葫芦娃1")
if match_obj:
# 获取匹配结果
result = match_obj.group()
print(result)
else:
# 匹配失败match_obj是一个None
print("匹配失败")
# 匹配银行卡密码中的其中一位
match_obj = re.match("[0123456789]", "7")
if match_obj:
# 获取匹配结果
result = match_obj.group()
print(result)
else:
# 匹配失败match_obj是一个None
print("匹配失败")
match_obj = re.match("[0-9]", "7")
if match_obj:
# 获取匹配结果
result = match_obj.group()
print(result)
else:
# 匹配失败match_obj是一个None
print("匹配失败")

运行结果:

h
H
葫芦娃1
7
7

3.3 示例3:\d

# \d = > [0-9]= >[0123456789]
match_obj = re.match("\d", "7")
if match_obj:
# 获取匹配结果
result = match_obj.group()
print(result)
else:
# 匹配失败match_obj是一个None
print("匹配失败")

运行结果:

7

3.4 示例4:\D

# \D: 匹配一个非数字字符
match_obj = re.match("\D", "a")
if match_obj:
# 获取匹配结果
result = match_obj.group()
print(result)
else:
# 匹配失败match_obj是一个None
print("匹配失败")

运行结果:

a

3.5 示例5:\s

# \s: 匹配一个空白字符,空格或者tab键
match_obj = re.match("葫芦娃\s[12]", "葫芦娃 1")
if match_obj:
# 获取匹配结果
result = match_obj.group()
print(result)
else:
# 匹配失败match_obj是一个None
print("匹配失败")

运行结果:

葫芦娃 1

3.6 示例6:\S

match_obj = re.match("葫芦娃\S[12]", "葫芦娃+1")
if match_obj:
# 获取匹配结果
result = match_obj.group()
print("没空白的匹配:", result)
else:
# 匹配失败match_obj是一个None
print("没空白的匹配:匹配失败")

运行结果:

没空白的匹配: 葫芦娃+1

3.7 示例7:\w

# \w: 匹配一个字母、数字、下划线、汉字
match_obj = re.match("\w", "哈")
if match_obj:
# 获取匹配结果
result = match_obj.group()
print(result)
else:
# 匹配失败match_obj是一个None
print("匹配失败")

运行结果:

3.8 示例8:\W

# 匹配特殊字符中的一位
match_obj = re.match("\W", "&")
if match_obj:
# 获取匹配结果
print(match_obj.group())
else:
print("匹配失败")

运行结果:

&

4 匹配多个字符

代码功能
*匹配前一个字符出现0次或者无限次,即可有可无
+匹配前一个字符出现1次或者无限次,即至少有1次
?匹配前一个字符出现1次或者0次,即要么有1次,要么没有
{m}匹配前一个字符出现m次
{m,n}匹配前一个字符出现从m到n次

4.1 示例1:*

需求:匹配出一个字符串第一个字母为大小字符,后面都是小写字母并且这些小写字母可 有可无

# * 匹配前一个字符出现0次或者无限次,即可有可无
import re
ret = re.match("[A-Z][a-z]*","M")
print(ret.group())
ret = re.match("[A-Z][a-z]*","MnnM")
print(ret.group())
ret = re.match("[A-Z][a-z]*","Aabcdef")
print(ret.group())

运行结果:

M
Mnn
Aabcdef

4.2 示例2:+

需求:匹配一个字符串,第一个字符是t,最后一个字符串是o,中间至少有一个字符

import re
match_obj = re.match("t.+o", "two")
if match_obj:
print(match_obj.group())
else:
print("匹配失败")

运行结果:

two

4.3 示例3:?

需求:匹配出这样的数据,但是https 这个s可能有,也可能是http 这个s没有

match_obj = re.match("https?", "http")
if match_obj:
print(match_obj.group())
else:
print("匹配失败")

运行结果:

http

4.4 示例4:{m}

# {m}: 匹配前一个字符串必须出现m次
match_obj = re.match("ht{2}p", "http")
if match_obj:
# 获取匹配结果
result = match_obj.group()
print(result)
else:
print("匹配失败")

运行结果:

http

4.5 示例5:{m,n}

# {m, n}: 匹配前一个字符串最少出现m次,最多出现n次
match_obj = re.match("ht{1,3}p", "httttp")
if match_obj:
# 获取匹配结果
result = match_obj.group()
print(result)
else:
print("匹配失败")
# 扩展: {m, }:匹配前一个字符串至少出现m次
match_obj = re.match("ht{2,}p", "htttttp")
if match_obj:
# 获取匹配结果
result = match_obj.group()
print(result)
else:
print("匹配失败")

运行结果:

匹配失败
htttttp

5 匹配开头和结尾

代码功能
^匹配字符串开头, [^指定字符]: 表示除了指定字符都匹配
$匹配字符串结尾

5.1 示例1:^

# 匹配以数字开头
match_obj = re.match("^\d.*", "1abc")
if match_obj:
# 获取匹配结果
result = match_obj.group()
print(result)
else:
print("匹配失败")

运行结果:

1abc

5.2 示例2:$

match_obj = re.match(".*\d$", "aa3")
if match_obj:
# 获取匹配结果
result = match_obj.group()
print(result)
else:
print("匹配失败")

运行结果:

aa3

5.3 示例3:^ 和 $

# 匹配以数字开头中间内容不管以数字结尾
match_obj = re.match("^\d.*\d$", "2asdfa3")
if match_obj:
# 获取匹配结果
result = match_obj.group()
print(result)
else:
print("匹配失败")
# [^指定字符] 表示除了指定字符都匹配
# [^47] 除了4和7都匹配
# ^: 表示以指定字符串开头
# [^]: 表示除了指定字符串都匹配
match_obj = re.match("^\d.*[^47]$", "2asdfa7")
if match_obj:
# 获取匹配结果
result = match_obj.group()
print(result)
else:
print("匹配失败")

运行结果:

2asdfa3
匹配失败

6 匹配分组

代码功能
|匹配左右任意一个表达式
(ab)将括号中字符作为一个分组
\num引用分组num匹配到的字符串
(?P)分组起别名
(?P=name)引用别名为name分组匹配到的字符串

6.1 示例1:|

# 水果列表
fruit_list = ['apple', 'banana', 'orage', 'pear', 'peach']
for value in fruit_list:
# 根据每一个字符串,使用正则表达式进行匹配
# | 匹配左右任意一个表达式
match_obj = re.match("banana|pear", value)
if match_obj:
result = match_obj.group()
print("我想吃的水果:", result)
else:
print("我不想吃的水果:", value)

运行结果:

我不想吃的水果: apple
我想吃的水果: banana
我不想吃的水果: orage
我想吃的水果: pear
我不想吃的水果: peach

6.2 示例2:( )

# 匹配出163、126、qq等邮箱
# \.: 表示对正则表达式里面的.进行了转义,变成了一个普通点,只能匹配.字符
# (163|126|qq) 表示一个分组,出现一个小括号就表示一个分组,分组是从1开始的
# 如果出现多个小括号,分组的顺序是从左到右一次排序
match_obj = re.match("[a-zA-Z0-9_]{4,20}@(163|126|qq)\.com", "hello@163.com")
if match_obj:
# 获取整个匹配的数据,如果使用分组数的化,默认是0
result = match_obj.group(0)
# 获取匹配分组数据
type = match_obj.group(1)
print(type)
print(result)
else:
print("匹配失败")
# "qq:3014587"
match_obj = re.match("(qq:)([1-9]\d{4,11})", "qq:666666")
if match_obj:
result = match_obj.group()
print(result)
result = match_obj.group(1)
print(result)
result = match_obj.group(2)
print(result)
else:
print("匹配失败")

运行结果:

163
hello@163.com
qq:666666
qq:
666666

6.3 示例3:\num

需求:匹配出hh

match_obj = re.match("<[a-zA-Z1-6]+>.*</[a-zA-Z1-6]+>", "<html>hh</div>")
if match_obj:
print(match_obj.group())
else:
print("匹配失败")
match_obj = re.match("<([a-zA-Z1-6]+)>.*</\\1>", "<html>hh</html>")
if match_obj:
print(match_obj.group())
else:
print("匹配失败")

运行结果:

<html>hh</div>
<html>hh</html>

需求:匹配出

www.baidu.com

match_obj = re.match("<([a-zA-Z1-6]+)><([a-zA-Z1-6]+)>.*</\\2></\\1>", "<html><h1>www.baidu.com</h1></html>")
if match_obj:
print(match_obj.group())
else:
print("匹配失败")

运行结果:

<html>\<h1>www.baidu.com\</h1>\</html>

6.4 示例4:(?P) (?P=name)

# <html><h1>www.itcast.cn</h1></html>
match_obj = re.match("<(?P<name1>[a-zA-Z1-6]+)><(?P<name2>[a-zA-Z1-6]+)>.*</(?P=name2)></(?P=name1)>", "<html><h1>www.baidu.com</h1></html>")
if match_obj:
result = match_obj.group()
print(result)
else:
print("匹配失败")

运行结果:

<html><h1>www.baidu.com</h1></html>

7 python中常用方法介绍

三个函数用于查找匹配match()、search()、findall(),一个函数sub()用于替换,一个函数split()用于切分字符串。

  • match():匹配字符串的开头,如果开头匹配不上,则返回None;
  • search():扫描整个字符串,匹配后立即返回,不在往后面匹配;
  • findall():扫描整个字符串,以列表形式返回所有的匹配值;
  • compile():将字符串编译成正则表达式对象,供 match() 、 search() 和findall()函数使用;
  • sub():扫描整个字符串,用于替换字符串的某些值;
  • split():扫描整个字符串,按照指定分隔符切分字符串;
s1 = 'ab少cd年abc'
r2 = re.search('b',s1)
r2.group()
# b
r3 = re.findall('[a|b]',s1)
r3.group()
# ['a', 'b', 'a', 'b']
r4 = re.findall('f',s1)
r4.group()
# []

下面我们根据一个爬虫经常见到的html格式数据,使用正则表达式,获取其中的li标签,或者获取其中的href属性,应该怎么做呢?

html = '''<html> <head lang="en"> <title>Title</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> </head> <body> <div id="content"> <ul id="ul1"> <li>first</li> <li>second</li> <li>third</li> </ul> <ul id="ul2"> <li>alpha</li> <li>beta</li> </ul> </div> <div id="url"> <a href="http:www.baidu.com" title="baidu">baidu</a> <a href="http:www.csdn.net" title="csdn">csdn</a> </div> </body> </html> '''
# 获取li标签
re.findall('<li>(.*?)</li>',html)
# ['first', 'second', 'third', 'alpha', 'beta']
# 获取href属性
re.findall('<a href="(.*?)" ',html)
# ['http:www.baidu.com', 'http:www.csdn.net']

操作其实很简单,固定写法:首尾照抄字符串源代码,我们想要的东西使用()小括号,括起来,里面写上 .*?

上面提到了一个.与.?,其中.表示贪婪匹配,.?表示非贪婪匹配。

  • . 可以匹配除了换行符以外的所有字符;
  • *表示匹配前面的字符无限次;
  • ?前面紧挨的元素,最多匹配一次;
# '\D{3,5}'表示匹配非数字3-5次。
s3 = '12one34two56three78four'
# 这里没有指定最大匹配次数,因此默认会替换所有的匹配值
re.sub('\D{3,5}','字母',s3)
# 12字母34字母56字母78字母
# 这里指定最大匹配次数count=2,因此只会替换前2个匹配值
re.sub('\D{3,5}','字母',s3,2)
# 12字母34字母56three78four
# 如果count=3,则会替换3个匹配值
re.sub('\D{3,5}','字母',s3,3)
# 12字母34字母56字母78four
# '\D'表示匹配非数字
s4 = '136-3456-7413'
# 这里如果不指定“最大分割次数”,则是不限次数切分
re.split('\D',s4)
# ['136', '3456', '7413']
# 如果指定最大分割次数maxsplit=1,那么就只以第一个分隔符,进行切分
re.split('\D',s4,1)
# ['136', '3456-7413']
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Python正则表达式是一种强大的字符串处理工具,它可以用于在文本中查找、替换和提取特定模式的字符串。在Python中使用正则表达式,需要先导入`re`模块。 下面是一个简单的示例代码,演示了如何使用正则表达式在字符串中匹配特定的模式: ```python import re # 定义一个待匹配的字符串 string = "Hello, my email address is [email protected]" # 定义一个正则表达式模式,用于匹配邮箱地址 pattern = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b' # 使用re模块的findall()方法进行匹配 matches = re.findall(pattern, string) # 输出匹配的结果 print(matches) ``` 运行以上代码,输出结果会是`['[email protected]']`,即匹配到了字符串中的邮箱地址。 在正则表达式中,可以使用一些特殊字符和元字符来构建匹配模式。例如,`r'\b'`表示单词边界,`[A-Za-z0-9._%+-]`表示匹配字母、数字、点、下划线、百分号、加号和减号等字符。 除了匹配字符,还可以使用一些特殊的元字符来表示数量和位置。例如,`+`表示前面的字符出现一次或多次,`*`表示前面的字符出现零次或多次,`{2,}`表示前面的字符出现至少两次。 以上只是简单介绍了Python正则表达式的基本用法,实际上正则表达式还有很多高级用法和特性。你可以参考Python官方文档中关于`re`模块的详细说明来深入学习和理解正则表达式的使用方法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

赵广陆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值