Python字符串及正则表达式(十一):正则表达式、使用re模块实现正则表达式操作

前言:在 Python 编程的广阔天地中,字符串处理无疑是一项基础而关键的技能。正则表达式,作为处理字符串的强大工具,以其灵活的模式匹配能力,在文本搜索、数据清洗、格式验证等领域发挥着不可替代的作用。本系列博客已经带领大家逐步深入了 Python 字符串操作的多个方面,从基础的字符串操作到高级的文本处理技术。

正则表达式的魔力:

正则表达式(Regular Expression,简称 regex)是一种用于字符串搜索和操作的强大工具,它使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。在 Python 中,re 模块提供了对正则表达式的全面支持,使得开发者能够轻松实现复杂的字符串匹配和处理任务。

在本篇博客中,我们将聚焦于如何使用 Python 的 re 模块来实现正则表达式操作。文章将涵盖以下几个核心内容:

  1. 匹配字符串 :深入探讨 search()match() 方法,了解它们在字符串匹配中的差异和应用场景。
  2. 使用 findall() 方法:展示如何查找字符串中所有匹配正则表达式的子串。
  3. 替换字符串 :通过 sub() 方法,我们将学习如何将匹配到的字符串替换为新的字符串。
  4. 分割字符串 :使用正则表达式作为分隔符,通过 split() 方法对字符串进行分割。

学习目标:

通过本篇博客的学习,读者将能够:

  • 掌握 re 模块的基本用法,包括正则表达式的编译和基本操作。
  • 理解并应用不同的正则表达式模式,以解决实际的字符串处理问题。
  • 学会使用正则表达式进行字符串的搜索、替换和分割,提高代码的效率和可读性。

一、正则表达式

正则表达式是一种强大的文本处理工具,它可以帮助我们快速地搜索、替换、检查或解析字符串。在Python中,正则表达式通过re模块实现,提供了丰富的功能来处理复杂的文本匹配问题。本文将带你深入了解正则表达式的基本概念和在Python中的使用。

1、行定位符

  • ^:匹配输入字符串的开始位置。
  • $:匹配输入字符串的结束位置。

行定位符包括^$,分别用于匹配行的开始和结束。如:
^tm表达式表示要匹配字符串tm的开始位置是行头,如"tm equal Tomorrow Moon"可以匹配,而"Tomorrow Noon equal tm",则不匹配,后后者表达式则可以匹配:tm$

示例:

python 复制代码
import re

text = "Hello, world!"
match = re.search("^H", text)  # 匹配行首的H
print(match.group())  # 输出 H

2、元字符

元字符在正则表达式中有特殊含义,比如.*+?等。

  • .:匹配任意单个字符(除了换行符)。
  • *:匹配前一个字符0次或多次。
  • +:匹配前一个字符1次或多次。
  • ?:匹配前一个字符0次或1次。

示例:

python 复制代码
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次。

示例:

python 复制代码
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]+:匹配连续的多个汉字。

示例:

python 复制代码
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]

使用[^...]可以排除指定的字符。

示例:

python 复制代码
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)$

使用|可以实现选择字符的效果,匹配多个选项中的一个。

示例:

python 复制代码
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}

使用\可以转义元字符,使其失去特殊含义。

示例:

python 复制代码
import re

text = "3.14 is pi."
matches = re.findall(r"\.", text)  # 匹配点号
print(matches)  # 输出 ['.']

8、分组

使用()可以创建一个分组,用于捕获匹配的子字符串。

示例:

python 复制代码
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中使用正则表达式时,是将其作为模式字符串使用的。例如,如果你想匹配不是字母的字符,可以使用如下代码:

python 复制代码
'[^a-zA-Z]'

这将匹配任何非字母字符。

然而,如果你想匹配以特定字母开头的单词,并将这个正则表达式转换为模式字符串,你不能直接在其两侧添加定界符。例如,下面的代码是不正确的:

python 复制代码
'\bm\w*\b'

在这个例子中,\b 是一个单词边界的元字符,而 \w* 匹配任意数量的字母、数字或下划线。但是,如果我们直接使用这个字符串作为正则表达式,它将不会按预期工作,因为反斜杠 \ 在字符串中需要被转义。

为了正确地使用这个正则表达式,我们需要对反斜杠进行转义,转换后的结果如下:

python 复制代码
'\\bm\\w*\\b'

在Python中,由于字符串中的反斜杠也是一个特殊字符,所以我们需要使用两个反斜杠 \\ 来表示一个字面量的反斜杠。

原生字符串

由于模式字符串中可能包含大量的特殊字符和反斜杠,所以需要写为原生字符串,即在模式字符串前加 rR。例如,上面的模式字符串采用原生字符串表示如下:

python 复制代码
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, \sS 只进行 ASCII 匹配(仅适用于 Python 3.X)。
I 或 IGNORECASE 执行不区分字母大小写的匹配。
M 或 MULTILINE ^$ 用于包括整个字符串的开始和结尾的每一行(默认情况下,仅适用于整个字符串的开始和结尾处)。
S 或 DOTALL 使用 . 字符匹配所有字符,包括换行符。
X 或 VERBOSE 忽略模式字符串中未转义的空格和注释,允许在正则表达式中加入注释以提高可读性。

这些标志可以用于 re 模块中的各种函数,如 search(), match(), findall(), sub() 等,以修改正则表达式的匹配行为。例如,使用 re.IGNORECASE 可以让匹配过程不区分大小写,而 re.MULTILINE 可以让 ^$ 在多行模式下匹配每一行的开始和结束。

示例

侧如,匹配字符串是否以mr_开头,不区分字母大小写,代码如下:

python 复制代码
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_SHOPmr_开头,将返回一个 Match 对象,而字符串项目名称 MR_SHOP没有以mr_开头,将返回None。这是因为match()方法从字符串的开始位置开始匹配,当第一个字符不符合条件时,则不再进行匹配,直接返回None

Match 对象中包含了匹配值的位置和匹配数据。其中,要获取匹配值的起始位置可以使用Match 对象的start()方法:要获取匹配值的结束位置可以使用end()方法;通过span()方法可以返回匹配位置的元组:通过string属性可以获取要匹配的字符串。例如下面的代码:

python 复制代码
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 -验证输入的手机号码是否为中国移动的号码

python 复制代码
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 -验证是否出现危险字符

python 复制代码
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_开头的字符串,代码如下:

python 复制代码
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)                              #输出匹配结果

如果在指定的模式字符串中包含分组,则返回与分组匹配的文本列表。例如:

python 复制代码
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 可以是以下值的组合:

示例

python 复制代码
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是我们之前定义的手机号码正则表达式,replacement1XXXXXXXXXXstring是包含手机号码的原始字符串。
      打印结果
  • print(result):这行代码打印出替换后的结果,即把手机号码中间的数字替换为X后的字符串。

实例训练40 -替换出现危险字符

python 复制代码
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中提取请求地址和各个参数

python 复制代码
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 -打印象棋口诀

pyhon 复制代码
# 定义象棋口诀字符串
chess_proverb = """
马走日
象走田
车走直路炮翻山
士走斜线护将边
小卒一去不回还
"""

# 打印象棋口诀
print(chess_proverb)

实例训练43 -显示实时天气预报

python 复制代码
# 定义天气预报数据
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 -模拟微信抢红包

python 复制代码
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 正则表达式的精髓,为你的编程技能增添一抹亮色。

相关推荐
SomeB1oody23 分钟前
【Rust自学】4.1. 所有权:栈内存 vs. 堆内存
开发语言·后端·rust
toto41225 分钟前
线程安全与线程不安全
java·开发语言·安全
深度学习lover28 分钟前
[项目代码] YOLOv8 遥感航拍飞机和船舶识别 [目标检测]
python·yolo·目标检测·计算机视觉·遥感航拍飞机和船舶识别
水木流年追梦1 小时前
【python因果库实战10】为何需要因果分析
开发语言·python
m0_675988232 小时前
Leetcode2545:根据第 K 场考试的分数排序
python·算法·leetcode
w(゚Д゚)w吓洗宝宝了2 小时前
C vs C++: 一场编程语言的演变与对比
c语言·开发语言·c++
AI人H哥会Java2 小时前
【Spring】Spring的模块架构与生态圈—Spring MVC与Spring WebFlux
java·开发语言·后端·spring·架构
开心工作室_kaic2 小时前
springboot461学生成绩分析和弱项辅助系统设计(论文+源码)_kaic
开发语言·数据库·vue.js·php·apache
觉醒的程序猿3 小时前
vue2设置拖拽选中时间区域
开发语言·前端·javascript
明月看潮生3 小时前
青少年编程与数学 02-004 Go语言Web编程 12课题、本地数据存储
开发语言·青少年编程·本地存储·编程与数学·goweb