前言:在 Python 编程的广阔天地中,字符串处理无疑是一项基础而关键的技能。正则表达式,作为处理字符串的强大工具,以其灵活的模式匹配能力,在文本搜索、数据清洗、格式验证等领域发挥着不可替代的作用。本系列博客已经带领大家逐步深入了 Python 字符串操作的多个方面,从基础的字符串操作到高级的文本处理技术。
正则表达式的魔力:
正则表达式(Regular Expression,简称 regex)是一种用于字符串搜索和操作的强大工具,它使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。在 Python 中,re
模块提供了对正则表达式的全面支持,使得开发者能够轻松实现复杂的字符串匹配和处理任务。
在本篇博客中,我们将聚焦于如何使用 Python 的 re
模块来实现正则表达式操作。文章将涵盖以下几个核心内容:
- 匹配字符串:深入探讨
search()
和match()
方法,了解它们在字符串匹配中的差异和应用场景。 - 使用
findall()
方法:展示如何查找字符串中所有匹配正则表达式的子串。 - 替换字符串:通过
sub()
方法,我们将学习如何将匹配到的字符串替换为新的字符串。 - 分割字符串:使用正则表达式作为分隔符,通过
split()
方法对字符串进行分割。
学习目标:
通过本篇博客的学习,读者将能够:
- 掌握
re
模块的基本用法,包括正则表达式的编译和基本操作。 - 理解并应用不同的正则表达式模式,以解决实际的字符串处理问题。
- 学会使用正则表达式进行字符串的搜索、替换和分割,提高代码的效率和可读性。
一、正则表达式
正则表达式是一种强大的文本处理工具,它可以帮助我们快速地搜索、替换、检查或解析字符串。在Python中,正则表达式通过re
模块实现,提供了丰富的功能来处理复杂的文本匹配问题。本文将带你深入了解正则表达式的基本概念和在Python中的使用。
1、行定位符
^
:匹配输入字符串的开始位置。$
:匹配输入字符串的结束位置。
行定位符包括^
和$
,分别用于匹配行的开始和结束。如:
^tm
表达式表示要匹配字符串tm的开始位置是行头,如"tm equal Tomorrow Moon"可以匹配,而"Tomorrow Noon equal tm",则不匹配,后后者表达式则可以匹配:tm$
示例:
import re
text = "Hello, world!"
match = re.search("^H", text) # 匹配行首的H
print(match.group()) # 输出 H
2、元字符
元字符在正则表达式中有特殊含义,比如.
、*
、+
、?
等。
.
:匹配任意单个字符(除了换行符)。*
:匹配前一个字符0次或多次。+
:匹配前一个字符1次或多次。?
:匹配前一个字符0次或1次。
示例:
import re
text = "I love apples and bananas."
matches = re.findall("a.*e", text) # 匹配以a开头,以e结尾的任意字符串
print(matches) # 输出 ['love', 'and bananas']
常用元字符表:
元字符 | 说明 | 举例 |
---|---|---|
. | 匹配除换行符外的任意字符 | 可以匹配 “m\nAn” 中的 m、A、n |
\w | 匹配字母、数字、下划线或汉字 | 可以匹配 “m中7b\n” 中的 m、中、7、b,但不能匹配 “\n” |
\W | 匹配非字母、数字、下划线或汉字的字符 | 可以匹配 “m中7b\n” 中的 “\n”,但不能匹配 “m、中、7、b” |
\s | 匹配单个空白符(包括空格、Tab键、换行符等) | 可以匹配 “mr\tMR” 中的 \t |
\S | 匹配单个空白符(包括Tab键和换行符)外的所有字符 | 可以匹配 “mr\tMR” 中的 m、r、M、R |
\b | 匹配单词的开始或结束,单词的分界符提出是空格。标点符号或者换行 | 在 “I like mr or am” 字符串中,\bm 与 “mr” 中的m相匹配,但是与am中的m不匹配 |
\d | 匹配数字 | \d可以与“m7ri"中的字符7匹配 |
3、限定符
限定符用于指定匹配次数。
{n}
:恰好匹配n次。{n,}
:至少匹配n次。{n,m}
:最少匹配n次且最多m次。
示例:
import re
text = "abc123"
match = re.search("a{2}", text) # 匹配两个连续的a
print(match.group()) # 输出 None,因为没有两个连续的a
常用限定符表:
限定符 | 说明 | 举例 |
---|---|---|
? | 匹配前面的字符零次或一次 | colou?r 可以匹配 “colour” 和 “color” |
+ | 匹配前面的字符一次或多次 | go+gle 可以匹配 “gogle” 到 “goo…gle” |
* | 匹配前面的字符零次或多次 | go*gle 可以匹配 “ggle” 到 “goo…gle” |
{n} | 匹配前面的字符n次 | go{2}gle 只匹配 “google” |
{n,} | 匹配前面的字符最少n次 | go{2,}gle 可以匹配 “google” 到 “goo…gle” |
{n,m} | 匹配前面的字符最少n次,最多m次 | employe{0,2} 可以匹配 “employ”、“employe” 和 “employee” |
4、字符类
字符类用于匹配一组指定的字符。在正则表达式中,可以通过方括号 []
来定义字符类。以下是一些示例:
[abc]
:匹配a、b或c中的任意一个。[^abc]
:匹配除了a、b、c之外的任意字符。[aeiou]
:匹配任何一个英文元音字母。[.?!]
:匹配标点符号,包括点号(.
)、问号(?
)或感叹号(!
)。[0-9]
:匹配任何一个数字,与\d
相同。[a-z0-9A-Z]
:匹配任何一个字母或数字,与\w
相同,但请注意\w
还包括下划线。[\u4e00-\u9fa5]
:匹配任何一个汉字。Unicode 范围\u4e00
到\u9fa5
涵盖了常用的汉字字符集。[\u4e00-\u9fa5]+
:匹配连续的多个汉字。
示例:
import re
text = "I have 3 apples and 5 bananas."
matches = re.findall(r"[0-9]", text) # 匹配所有数字
print(matches) # 输出 ['3', '5']
5、排除字符
排除字符用于匹配不符合指定字符集合的字符串。在正则表达式中,可以通过在方括号内使用 ^
符号来实现排除。以下是一些示例:
[^a-z]
:匹配任何一个不是小写字母的字符。[^A-Z]
:匹配任何一个不是大写字母的字符。[^0-9]
:匹配任何一个不是数字的字符。[^a-zA-Z]
:匹配任何一个不是字母的字符。[^\w]
:匹配任何一个不是字母、数字或下划线的字符。[^a-zA-Z0-9]
:匹配任何一个不是字母或数字的字符,等同于[^\w]
。
使用[^...]
可以排除指定的字符。
示例:
import re
text = "Hello, world!"
matches = re.findall("[^a-z]", text) # 匹配所有非小写字母的字符
print(matches) # 输出 ['H', ',', ' ', '!']
请注意,^
符号在方括号内表示排除,而在方括号外则表示行的开始。在您提供的表达式 $$[^{\wedge} a-z A-Z]$$
中,似乎存在一些格式错误。正确的表达式应该是 [^\w]
用于匹配非字母字符,或者 [^a-zA-Z]
用于匹配非字母字符。如果需要匹配非字母和非数字的字符,可以使用 [^\w]
或 [^a-zA-Z0-9]
。
6、选择字符
拿身份证号的规则举例,身份证号码长度为15位或者18位。如果为15位,则是全数字;如果为18位,则前17位为数字,最后一位是校验码,可能为数字或字符X。根据这些条件选择为逻辑,所以需要使用选择字符|
来实现,该字符可以理解为"或",匹配身份证的表达式如下:
(^\d{15}$)|(^\d{18}$)|(^\d{17})(\d|X|x)$
使用|
可以实现选择字符的效果,匹配多个选项中的一个。
示例:
import re
text = "I have apples and bananas."
matches = re.findall("apples|bananas", text) # 匹配apples或bananas
print(matches) # 输出 ['apples', 'bananas']
7、转义字符
正则表达式中的转义字符\
和python中的大同小异,都是将特殊字符(如.``?``\
等)变为普通的字符,比如IP地址实例,用正则表达式匹配诸如127.0.0.1
格式的IP地址,如果直接使用点字符,格式如:[1-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}
,这样就会出现问题,因为.
可以匹配任意一个字符,这样不仅是127.0.0.1
这样的ip可以匹配出来,连127101011
这样的字符串也会被匹配出来,所以在使用.
时,需要使用转义字符\
,修改后的正则表达式为:[1-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}
使用\
可以转义元字符,使其失去特殊含义。
示例:
import re
text = "3.14 is pi."
matches = re.findall(r"\.", text) # 匹配点号
print(matches) # 输出 ['.']
8、分组
使用()
可以创建一个分组,用于捕获匹配的子字符串。
示例:
import re
text = "My phone number is 123-456-7890."
match = re.search(r"(\d{3})-(\d{3})-(\d{4})", text) # 分组匹配电话号码
if match:
print(match.group(1), match.group(2), match.group(3)) # 输出 123 456 7890
9、在Python中使用正则表达式
在Python中使用正则表达式时,是将其作为模式字符串使用的。例如,如果你想匹配不是字母的字符,可以使用如下代码:
'[^a-zA-Z]'
这将匹配任何非字母字符。
然而,如果你想匹配以特定字母开头的单词,并将这个正则表达式转换为模式字符串,你不能直接在其两侧添加定界符。例如,下面的代码是不正确的:
'\bm\w*\b'
在这个例子中,\b
是一个单词边界的元字符,而 \w*
匹配任意数量的字母、数字或下划线。但是,如果我们直接使用这个字符串作为正则表达式,它将不会按预期工作,因为反斜杠 \
在字符串中需要被转义。
为了正确地使用这个正则表达式,我们需要对反斜杠进行转义,转换后的结果如下:
'\\bm\\w*\\b'
在Python中,由于字符串中的反斜杠也是一个特殊字符,所以我们需要使用两个反斜杠 \\
来表示一个字面量的反斜杠。
原生字符串
由于模式字符串中可能包含大量的特殊字符和反斜杠,所以需要写为原生字符串,即在模式字符串前加 r
或 R
。例如,上面的模式字符串采用原生字符串表示如下:
r'\bm\w*\b'
在编写模式字符串时,并不是所有的反斜杠都需要进行转义。例如,正则表达式 ^\d{8}$
中的反斜杠就不需要转义,因为其中的 \d
并没有特殊意义。不过,为了编写方便,本书中的正则表达式都采用原生字符串表示。
通过这种方式,我们可以确保在Python中正确地使用正则表达式,避免因转义问题导致的错误。
二、使用re模块实现正则表达式操作
正则表达式是处理字符串的强大工具,Python 的 re
模块提供了丰富的功能来实现各种正则表达式操作。在本文中,我们将探讨如何使用 re
模块进行字符串匹配、替换和分割。
1. 匹配字符串
① 使用 match()
方法进行匹配
match()
方法也用于匹配模式,但它只从字符串的开始位置匹配。如果模式匹配成功,它同样会返回一个 Match
对象。否则返回None
,语法格式如下:
re.match(pattern,string,[flags])
match()
方法是 Python re
模块中的一个函数,用于从字符串的起始位置匹配正则表达式模式。下面是 match()
方法的参数说明:
参数说明
-
pattern:这是一个字符串,表示你要匹配的正则表达式模式。
-
string:这是要进行匹配操作的原始字符串。
-
flags(可选):这是一个可选的标志参数,用于改变正则表达式匹配的方式。
flags
可以是以下值的组合:
正则表达式中的常用标志表:
标志 | 说明 |
---|---|
A 或 ASCII | 对于 \w , \W , \b , \B , \d , \D , \s 和 S 只进行 ASCII 匹配(仅适用于 Python 3.X)。 |
I 或 IGNORECASE | 执行不区分字母大小写的匹配。 |
M 或 MULTILINE | 将 ^ 和 $ 用于包括整个字符串的开始和结尾的每一行(默认情况下,仅适用于整个字符串的开始和结尾处)。 |
S 或 DOTALL | 使用 . 字符匹配所有字符,包括换行符。 |
X 或 VERBOSE | 忽略模式字符串中未转义的空格和注释,允许在正则表达式中加入注释以提高可读性。 |
这些标志可以用于 re
模块中的各种函数,如 search()
, match()
, findall()
, sub()
等,以修改正则表达式的匹配行为。例如,使用 re.IGNORECASE
可以让匹配过程不区分大小写,而 re.MULTILINE
可以让 ^
和 $
在多行模式下匹配每一行的开始和结束。
示例
侧如,匹配字符串是否以mr_
开头,不区分字母大小写,代码如下:
import re
pattern = r'mr_\w+' #模式字符串
string = 'MR_SHOP mr_shop' #要匹配的字符串
match = re.match(pattern, string, re.I) #匹配字符串,不区分大小写
print(match) #输出匹配结果
string = '项目名称MR_SHOP mr_shop'
match = re.match(pattern, string, re.I) #匹配字符串,不区分大小写
print(match) #输出匹配结果
从上面的执行结果(报错)中可以看出,字符串MR_SHOP
以mr_
开头,将返回一个 Match 对象,而字符串项目名称 MR_SHOP
没有以mr_
开头,将返回None
。这是因为match()
方法从字符串的开始位置开始匹配,当第一个字符不符合条件时,则不再进行匹配,直接返回None
。
Match 对象中包含了匹配值的位置和匹配数据。其中,要获取匹配值的起始位置可以使用Match 对象的start()
方法:要获取匹配值的结束位置可以使用end()
方法;通过span()
方法可以返回匹配位置的元组:通过string属性可以获取要匹配的字符串。例如下面的代码:
import re
pattern = r'mr_shop' #模式字符串
string = 'MR_SHOP mr_shop' #要匹配的字符串
match = re.match(pattern, string, re.I) #匹配字符串,不区分大小写
print('匹配值的起始位置:', match.start())
print('匹配值的结束位置:', match.end())
print('匹配位置的元组:', match.span())
print('要匹配的字符串:', match.string)
print('匹配数据:', match.group())
实例训练38 -验证输入的手机号码是否为中国移动的号码
import re #导入python的re模块
pattern = r'(13[4-9]\d{8})|(15[01289]\d{8})'
mobile = '13735222222'
match = re.match(pattern, mobile) #进行模块匹配
if match == None: #判断是否为None,为真表示匹配失败
print(mobile, '不是有效的中国移动手机号码。')
else:
print(mobile, '是有效的中国移动手机号码。')
mobile = '13144222221'
match = re.match(pattern, mobile) #进行模块匹配
if match == None: #判断是否为None,为真表示匹配失败
print(mobile, '不是有效的中国移动手机号码。')
else:
print(mobile, '是有效的中国移动手机号码。')
② 使用 search()
方法进行匹配
search()
方法在整个字符串中搜索第一个匹配的值,如果找到匹配项,则返回一个 Match
对象,否则返回 None
。语法格式如下:
re.search(pattern,string,[flags])
search()
方法是 Python re
模块中的一个函数,用于在整个字符串中搜索第一个匹配正则表达式模式的值。下面是 search()
方法的参数说明:
参数说明
-
pattern:这是一个字符串,表示你要匹配的正则表达式模式。
-
string:这是要进行匹配操作的原始字符串。
-
flags(可选):这是一个可选的标志参数,用于改变正则表达式匹配的方式。
flags
可以是以下值的组合:
示例,搜索第一个以mr_
开头的字符串,不区分字母大小写
import re
pattern = r'mr_\w+' #模式字符串
string = 'MR_SHOP mr_shop' #要匹配的字符串
match = re.search(pattern,string,re.I) #搜索字符串,不区分大小写
print(match) #输出匹配结果
string = '项目名称MR_SHOP mr_shop'
match = re.search(pattern,string,re.I) #搜索字符串,不区分大小写
print(match) #输出匹配结果
实例训练39 -验证是否出现危险字符
import re #导入re模块
pattern = r'(黑客)|(抓包)|(监听)|(Trojan)' # 模式字符串,包含黑客、抓包、监听、Trojan等词汇
# 第一段文本
about = '我是一名程序员,我喜欢看黑客方面的图书,想研究一下Trojan。'
match = re.search(pattern, about) #进行模糊匹配
if match == None: #判断是否为None,为真表示匹配失败
print(about, '@ 安全!')
else:
print(about, '@ 出现了危险词汇!')
# 第二段文本
about = '我是一名程序员,我喜欢看计算机网络方面的图书,喜欢开发网站。'
match = re.match(pattern, about) #进行模糊匹配
if match == None: #判断是否为None,为真表示匹配失败
print(about, '@ 安全!')
else:
print(about, '@ 出现了危险词汇!')
③ 使用 findall()
方法进行匹配
findall()方法用于在整个字符串中搜索所有符合正则表达式的字符串,并以列表的形式返回。如果成动,则返回包含匹配结构的列表,否则返回空列表。findall()方法的语法格式如下:
re.findall(pattern, string,[flags])
参数说明
- patem:表示模式字符串,由要匹配的正则表达式转换而来。
- string:表示要匹配的字符串。
-flags:可选参数,表示标志位,用于控制匹配方式,如是否区分字母大小写
示例,搜索以mr_
开头的字符串,代码如下:
import re
pattern = r'mr_\w+' #模式字符串
string = 'MR_SHOP mr_shop' #要匹配的字符串
match = re.findall(pattern,string,re.I) #搜索字符串,不区分大小写
print(match)
string = '项目名称MR_SHOP mr_shop'
match = re.findall(pattern,string) #搜索字符串,区分大小写
print(match) #输出匹配结果
如果在指定的模式字符串中包含分组,则返回与分组匹配的文本列表。例如:
import re
pattern = r'[1-9]{1,3}(\.[0-9]{1,3}){3}' #模式字符串
str1 ='127.0.0.1 192.168.1.66' #要配置的字符串
match = re.findall(pattern,str1) #进行模式匹配
print(match)
从上面的结果中可以看出,并没有得到匹配的地址,这是因为在模式字符串中出现了分组,所以得到的结果是根据分组进行匹配的结果,即(\.[0-9]{1,3})
匹配的结果。如果想获取整个模式字符串的匹配,可以将整个模式字符串使用一对小括号进行分组,然后在获取结果时,只取返回值列表的每个元素(是一个元组)的第1个元素。代码如下:
import re
pattern = r'([1-9]{1,3}(\.[0-9]{1,3}){3})' #模式字符串
str1 ='127.0.0.1 192.168.1.66' #要配置的字符串
match = re.findall(pattern,str1) #进行模式匹配
for item in match:
print(item[0])
2、 替换字符串
sub()
方法用于实现字符串替换,语法格式如下:
re.sub(pattern, repl,string, count, flags)
sub()
方法是 Python re
模块中的一个函数,用于替换字符串中的模式。下面是 sub()
方法的参数说明:
参数说明
-
pattern:这是一个字符串,表示你要匹配的正则表达式模式。
-
repl:这是替换文本,可以是一个字符串或者一个函数。如果是一个字符串,它将替换所有匹配的模式。如果是一个函数,这个函数将被调用,它的参数是每个匹配的
Match
对象,函数的返回值将用于替换。 -
string:这是要进行匹配和替换操作的原始字符串。
-
count(可选):这是一个整数,表示替换操作的最大次数。如果省略或设置为
0
,则替换所有匹配项。 -
flags(可选):这是一个可选的标志参数,用于改变正则表达式匹配的方式。
flags
可以是以下值的组合:
示例
import re
pattern = r'1[34578]\d{9}' #定义要替换的模式字符串
string = '中奖号码为:84978981 联系电话为:13611111111'
result = re.sub(pattern, '1XXXXXXXXXX', string) #替换字符串
print(result)
讲解:
① 导入模块
import re
:这行代码导入了Python的re
模块,re
模块是用于处理正则表达式的。
② 定义正则表达式模式pattern = r'1[34578]\d{9}'
:这行代码定义了一个正则表达式模式。r'...'
:这里的r
表示原始字符串(raw string),在原始字符串中,反斜杠\
不会被当作转义字符处理。1[34578]\d{9}
:这个正则表达式模式用于匹配手机号码。1
:手机号码以1开头。[34578]
:第二位数字是3、4、5、7或8中的一个。\d{9}
:后面跟着9位数字。
③ 定义字符串
string = '中奖号码为:84978981 联系电话为:13611111111'
:这行代码定义了一个包含中奖号码和联系电话的字符串,其中联系电话是一个手机号码。
④ 替换操作result = re.sub(pattern, '1XXXXXXXXXX', string)
:这行代码使用re.sub()
函数进行替换操作。re.sub(pattern, replacement, string)
:这个函数的作用是在string
中找到所有匹配pattern
的子串,并用replacement
替换它们。- 在这里,
pattern
是我们之前定义的手机号码正则表达式,replacement
是1XXXXXXXXXX
,string
是包含手机号码的原始字符串。
⑤ 打印结果
print(result)
:这行代码打印出替换后的结果,即把手机号码中间的数字替换为X
后的字符串。
实例训练40 -替换出现危险字符
import re #导入re模块
pattern = r'(黑客)|(抓包)|(监听)|(Trojan)' # 模式字符串,包含黑客、抓包、监听、Trojan等词汇
# 第一段文本
about = '我是一名程序员,我喜欢看黑客方面的图书,想研究一下Trojan。\n'
sub = re.sub(pattern,'@_@',about) #进行模糊匹配
print(sub)
about = '我是一名程序员,我喜欢看计算机网络方面的图书,喜欢开发网站'
sub = re.sub(pattern,'@_@',about) #进行模糊匹配
print(sub)
3、 使用正则表达式分割字符串
split()
方法用于实现根据正则表达式分割字符串,并以列表的形式返回。其作用同字符串对象的split()
方法类似,所不同的就是分割字符由模式字符串指定。spI0方法的语法格式:
re.split(pattern, string,[maxsplit], [flags])
参数说明:
- patem:表示模式字符串,由要匹配的正则表达式转换而来。
- sting:表示要匹配的字符串。
- maxsplit:可选参数,表示最大的拆分次数。
- fags:可选参数,表示标志位,用于控制匹配方式,如是否区分字母大小写。
示例:从给定的URL中提取请求地址和各个参数
import re
pattern = r'[?|&]' #定义分隔符
url = 'http://www.mingrisoft.com/login.jsp?username="mr"&pwd="mrssoft"'
result = re.split(pattern, url) #分割字符串
print(result)
实例训练41 -输出被@的好友名称(使用正则表达式)
import re
str1 = '@马哥教育 @马云 @马斯克'
pattern = r'\s*@'
list1 = re.split(pattern,str1) #用空格和@或单独的@分割字符串
print('您@的好友有: ')
for item in list1:
if item != '':
print(item)
通过这些基本的操作,你可以开始使用 Python 的 re
模块来处理复杂的字符串问题。正则表达式是一个强大的工具,但也需要仔细设计以避免性能问题或难以理解的代码。
实例训练42 -打印象棋口诀
# 定义象棋口诀字符串
chess_proverb = """
马走日
象走田
车走直路炮翻山
士走斜线护将边
小卒一去不回还
"""
# 打印象棋口诀
print(chess_proverb)
实例训练43 -显示实时天气预报
# 定义天气预报数据
forecast = {
"date": "2023年12月1日",
"times": [
{"time": "13:00", "condition": "晴", "temp": "-14°C", "wind": "南风3级"},
{"time": "14:00", "condition": "晴", "temp": "-7°C", "wind": "西南风3级"},
{"time": "15:00", "condition": "晴", "temp": "-8°C", "wind": "西南风3级"},
{"time": "16:00", "condition": "晴", "temp": "-10°C", "wind": "西南风2级"},
{"time": "17:00", "condition": "晴", "temp": "-11°C", "wind": "西南风2级"},
{"time": "18:00", "condition": "晴", "temp": "-11°C", "wind": "南风2级"}
]
}
# 打印天气预报标题
print(forecast["date"], "天气预报:")
# 遍历并打印每个时间段的天气预报
for time_info in forecast["times"]:
print(f"{time_info['time']} 天气预报:{time_info['condition']} {time_info['temp']} {time_info['wind']}")
实例训练44 -模拟微信抢红包
import random
# 定义总金额和红包数量
total_amount = 100 # 总金额设置为100元
number_of_red_packets = 10 # 红包数量设置为10个
# 确保每个红包至少有1分钱
min_amount_per_packet = 0.01
# 计算剩余金额,用于分配红包
remaining_amount = total_amount
# 存储每个红包的金额
red_packets = []
# 分配红包
for i in range(number_of_red_packets - 1):
# 随机生成一个红包金额,确保剩余的红包总金额大于等于剩余红包数量的最小金额
max_amount = remaining_amount - (number_of_red_packets - i - 1) * min_amount_per_packet
amount = random.uniform(min_amount_per_packet, max_amount)
red_packets.append(round(amount, 2))
remaining_amount -= amount
# 最后一个红包的金额为剩余的所有金额
red_packets.append(round(remaining_amount, 2))
# 打印红包分配结果
print("模拟微信抢红包结果:")
for i, amount in enumerate(red_packets, start=1):
print(f"红包 {i}:{amount}元")
# 检查总金额是否正确
print(f"总金额:{sum(red_packets)}元")
实例训练45 -判断车牌归属地
def get_license_plate_location(license_plate):
# 定义中国大陆省份和直辖市的简称
locations = {
'京': '北京市',
'津': '天津市',
'冀': '河北省',
'晋': '山西省',
'蒙': '内蒙古自治区',
'辽': '辽宁省',
'吉': '吉林省',
'黑': '黑龙江省',
'沪': '上海市',
'苏': '江苏省',
'浙': '浙江省',
'皖': '安徽省',
'闽': '福建省',
'赣': '江西省',
'鲁': '山东省',
'豫': '河南省',
'鄂': '湖北省',
'湘': '湖南省',
'粤': '广东省',
'桂': '广西壮族自治区',
'琼': '海南省',
'渝': '重庆市',
'川': '四川省',
'贵': '贵州省',
'云': '云南省',
'藏': '西藏自治区',
'陕': '陕西省',
'甘': '甘肃省',
'青': '青海省',
'宁': '宁夏回族自治区',
'新': '新疆维吾尔自治区'
}
# 获取车牌号的前两位
prefix = license_plate[:2]
# 判断归属地
if prefix in locations:
return locations[prefix]
else:
return "未知地区"
# 示例
license_plate = "鄂A12345"
location = get_license_plate_location(license_plate)
print(f"车牌号 {license_plate} 的归属地是:{location}")
结语:正则表达式的世界博大精深,它的强大之处在于能够用极简洁的模式描述复杂的字符串结构。随着你对 re
模块的深入了解和实践,你将发现它在数据处理和文本分析中的巨大潜力。让我们一起开启这段探索之旅,掌握 Python 正则表达式的精髓,为你的编程技能增添一抹亮色。