Python字符串及正则表达式(十一):正则表达式、使用re模块实现正则表达式操作
前言:在 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 retext = "Hello, world!"
match = re.search("^H", text) # 匹配行首的H
print(match.group()) # 输出 H
2、元字符
元字符在正则表达式中有特殊含义,比如.
、*
、+
、?
等。
.
:匹配任意单个字符(除了换行符)。*
:匹配前一个字符0次或多次。+
:匹配前一个字符1次或多次。?
:匹配前一个字符0次或1次。
示例:
import retext = "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 retext = "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 retext = "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 retext = "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 retext = "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 retext = "3.14 is pi."
matches = re.findall(r"\.", text) # 匹配点号
print(matches) # 输出 ['.']
8、分组
使用()
可以创建一个分组,用于捕获匹配的子字符串。
示例:
import retext = "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_packetamount = 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 正则表达式的精髓,为你的编程技能增添一抹亮色。
相关文章:
Python字符串及正则表达式(十一):正则表达式、使用re模块实现正则表达式操作
前言:在 Python 编程的广阔天地中,字符串处理无疑是一项基础而关键的技能。正则表达式,作为处理字符串的强大工具,以其灵活的模式匹配能力,在文本搜索、数据清洗、格式验证等领域发挥着不可替代的作用。本系列博客已经…...
前端:金额高精度处理
Decimal 是什么 想必大家在用js 处理 数字的 加减乘除的时候,或许都有遇到过 精度不够 的问题,还有那些经典的面试题 0.20.1 ! 0.3, 至于原因,那就是 js 计算底层用的是 IEEE 754 ,精度上有限制, 那么Deci…...
WPF 依赖属性和附加属性
除了普通的 CLR 属性, WPF 还有一套自己的属性系统。这个系统中的属性称为依赖属性。 1. 依赖属性 为啥叫依赖属性?不叫阿猫阿狗属性? 通常我们定义一个普通 CLR 属性,其实就是获取和设置一个私有字段的值。假设声明了 100 个 …...
git merge 冲突 解决 show case
废话不多说,上 case!!! 1. 更新master分支 package org.example;public class Main {public static void main(String[] args) {System.out.println("--------Git冲突测试代码开始---------");System.out.println(&qu…...
小鹏“飞行汽车”上海首飞,如何保障智能出行的安全性?
近日,小鹏汇天的“陆地航母”飞行汽车在上海陆家嘴成功完成首飞,标志着飞行汽车时代在中国正式拉开序幕。作为一项突破性的科技创新,飞行汽车不仅将重塑我们的出行方式,还将深刻改变城市的交通格局。此次飞行不仅证明了飞行汽车的…...
分析excel硕士序列数据提示词——包含对特征的筛选,非0值的过滤
文章目录 1 分析出发点2 围绕出发点的文件分析3 功能模块计算重心相关性计算教学倾向百分比多列相关性计算结果封装证伪——过滤0后的交叉相关系数封装和总控——批量处理特征筛选——筛选提问倾向最大和最小的前五代码总的清洗1 分析出发点 写一个python代码,遍历"D:\Ba…...
sed | 一些关于 sed 的笔记
sed 总结 sed 语法sed [-hnV] [-e<script>] [-f<script文件>] [文本文件]--- 参数:-e<script> 以选项中指定的script 来处理输入的文本文件-f<script文件> 以选项中指定的script 文件来处理输入的文本文件动作说明:a 新增s 取代d 删除i 插入…...
如何重新设置VSCode的密钥环密码?
故障现象: 忘记了Vscode的这个密码: Enter password to unlock An application wants access to the keyring “Default ke... Password: The unlock password was incorrect Cancel Unlock 解决办法: 1.任意terminal下,输入如下…...
数据结构 (字符串:KMP)
KMP算法: 构造ne数组 和 匹配过程 vector<int> build_next(string s) { vector<int> ne(s.size()); ne[0] -1; for (int i 1, j -1; i < s.size(); i) { while (j ! -1 && s[i] ! s[j 1])j ne[j]; if (s[i…...
剑指offer搜索二维矩阵
题目连接 https://leetcode.cn/problems/search-a-2d-matrix-ii/’ 代码 自己想出来的 解法一 初始化两个指针,i0,j列数-1 若此时matrix[i][j]target 则返回true 若此时matrix[i][j]>target,表明在第j列中不可能存在target,因为列是升序的 若此时ma…...
【LIBS】开源库编译之OSQP
目录 编译环境源码下载本地编译交叉编译 编译环境 【LIBS】开源库编译之编译环境 源码下载 git clone --recursive --branch v0.6.3 https://github.com/osqp/osqp.git libosqp-0.6.3本地编译 cd libosqp-0.6.3cmake -B build_amd64 \-D CMAKE_BUILD_TYPERelease \-D CMAKE…...
【系统移植】制作SD卡启动——将uboot烧写到SD卡
在开发板上启动Linux内核,一般有两种方法,一种是从EMMC启动,还有一种就是从SD卡启动,不断哪种启动方法,当开发板上电之后,首先运行的是uboot。 制作SD卡启动,首先要将uboot烧写到SD卡ÿ…...
.NET重点
B/S C/S什么语言 B/S: 浏览器端:JavaScript,HTML,CSS 服务器端:ASP(.NET)PHP/JSP 优势:维护方便,易于升级和扩展 劣势:服务器负担沉重 C/S java/.NET/…...
米思奇图形化编程之ESP32控制LED灯闪烁方案实现
目录 一、项目概述 二、硬件准备 三、硬件连接 四、软件编程 五、验证效果 六、总结 一、项目概述 本项目使用米思奇图形化编程环境,编写micropython软件代码,实现了控制ESP32开发板上LED灯闪烁效果。该项目可为后续更复杂的物联网项目打下基础。…...
SMMU软件指南SMMU编程之全局错误和最小配置
安全之安全(security)博客目录导读 目录 一、全局错误 二、最小配置 一、全局错误 与编程接口相关的全局错误会报告到适当的 SMMU_(*_)GERROR 寄存器,而不是通过基于内存的事件队列。这些错误通常是严重的,例如导致 SMMU 停止向前推进。例如…...
JavaEE 导读与环境配置
JavaEE 介绍 Java EE(Java Platform Enterprise Edition), Java 平台企业版. 是JavaSE的扩展, ⽤于解决企业级的开发需求, 所以也可以称之为是⼀组⽤于企业开发的Java技术标准. 所以, 学习JavaEE主要是学习Java在企业中如何应⽤ 框架学习 Java EE 课程共涉及4个框架的学习: Spr…...
Cesium 实例化潜入潜出
Cesium 实例化潜入潜出 1、WebGL Instance 的原理 狭义的的WebGL 中说使用 Instance, 一般指使用 glDrawArraysInstanced 用于实例化渲染的函数。它允许在一次绘制调用中渲染多个相同的几何体实例,而无需为每个实例发起单独的绘制调用。 Three.js 就是使用这种方…...
设计模式——适配器模式
1. 定义 适配器模式(Adapter Pattern)属于结构型设计模式,它的主要作用是将一个类的接口转换成客户期望的另一个接口,使得原本由于接口不兼容而不能一起工作的类可以协同工作。简单来说,就是充当了不同接口之间的 “转…...
Linux安装Docker
如何在虚拟机中安装linux操作系统,参考文章: VMware下Centos7安装步骤-CSDN博客 使用Xshell链接到linux操作系统 执行命令,安装docker的底层工具 sudo yum install -y yum-utils device-mapper-persistent-data lvm2 增加阿里云docker下载仓…...
CH430N 插上电脑无反应
电路图,此处我用的是3.3V供电,现象就是插上USB,电脑没有反应。搜索也搜索不到 抄板请看自己是多少V供电 后来看到也有类似的 换了芯片后就好了。md新板子第一个芯片就是坏的,服了。...
Java实现贪吃蛇游戏
目录 一、项目结构 二、实现步骤 1. 创建 Snake 类 2. 创建 Food 类 3. 创建 GameBoard 类 4. 创建 SnakeGame 类 三、总结 贪吃蛇是一个经典的电子游戏,它的玩法非常简单,但又充满了挑战。玩家通过控制蛇的移动,吃到食物并不断成长&a…...
为SSH2协议服务器的用户设置密钥
目录 私钥的创建1. 在服务器上直接生成2. 如果需要配置免密登录3. 查看生成的密钥 导出私钥至SSH用户获取sudo权限 新的一台服务器类型是SSH2:这表示服务器支持SSH(Secure Shell)协议的第二个版本。SSH是一个网络协议,用于加密方式…...
最新版Chrome浏览器加ActiveX控件之多个VLC控件同时加载
背景 VLC Media Player 是一款可播放大多数格式,而无需安装编解码器包的媒体播放器。可以播放 MPEG-1、MPEG-2、MPEG-4、DivX、DVD/VCD、卫星数字电视频道、地面数字电视频道(digital terrestrial television channels)、在许多作业平台底下透过宽带 IPv4、IPv6 网络…...
sql server 查询对象的修改时间
sql server 不能查询索引的最后修改时间,可以查询表,存储过程,函数,pk 的最后修改时间使用以下语句 select * from sys.all_objects ob order by ob.modify_date desc 但可以参考一下统计信息的最后修改时间,因为索…...
均值聚类算法
K-均值聚类算法是一种常用的无监督学习算法,用于将数据集划分成K个不同的簇。该算法的步骤如下: 1. 选择聚类的个数K。 2. 随机初始化K个聚类中心。 3. 对每个数据点计算其与聚类中心的距离,并将其划分到最近的聚类中心所代表的簇。 4. 对每…...
django中cookie与session的使用
一、cookie cookie由服务器生成 ,存储在浏览器中的键值对数据,具有不安全性,对应敏感数据应该加密储存在服务端每个域名的cookie相互独立浏览器访问域名为A的url地址,会把A域名下的cookie一起传递到服务器cookie可以设置过期时间 django中设…...
Python 协程:并发编程的轻量级利器
一、协程是什么? 协程是一种比线程更加轻量级的存在。它可以在特定的点暂停执行,然后在后续某个时刻恢复执行,并且能够在暂停期间保存其执行状态。与传统的多线程模型不同,协程不需要操作系统进行线程上下文切换的开销,…...
理解JVM
JVM简介 JVM 是 Java Virtual Machine 的简称,意为 Java 虚拟机 虚拟机是指通过软件模拟的具有完整硬件功能的、运行在一个完全隔离的环境中的完整计算机系统 常见的虚拟机: JVM 、 VMwave 、 Virtual Box JVM 和其他两个虚拟机的区别: 1…...
GhostRace: Exploiting and Mitigating Speculative Race Conditions-记录
文章目录 论文背景Spectre-PHT(Transient Execution )Concurrency BugsSRC/SCUAF和实验条件 流程Creating an Unbounded UAF WindowCrafting Speculative Race ConditionsExploiting Speculative Race Conditions poc修复flush and reload 论文 https:/…...
【环境搭建】使用IDEA远程调试Dolphinscheduler
以Dolphinscheduler-3.1.8为例,先把容器起了: $ docker pull apache/dolphinscheduler-standalone-server:3.1.8 $ docker run -d -p 12345:12345 -p 25333:25333 -p 5005:5005 -d apache/dolphinscheduler-standalone-server:3.1.8下载Dolphinschedule…...
强基计划之编程:开启科研精英培养新路径
强基计划之编程:开启科研精英培养新路径 一、强基计划概述 1. 出台背景 在 2003 年,教育部开启高校自主招生改革,于探索综合评价学生、破除招生“唯分数论”等方面收获一定成效。相关调查研究显示,自主招生所录取的学生在入校后…...
奇怪问题| Chrome 访问csdn 创作中心的时候报错: 服务超时,请稍后重试
Chrome 访问csdn 创作中心的时候报错: 服务超时,请稍后重试用无痕浏览器可以正常访问 关闭代理无效清缓存和Cookies无效。考虑无痕浏览器模式下插件不生效,尝试把chrome 插件也禁用,发现有效,是该扩展程序的缘故...
Spring Boot 教程之三十六:实现身份验证
如何在 Spring Boot 中实现简单的身份验证? 在本文中,我们将学习如何使用 Spring设置和配置基本身份验证。身份验证是任何类型的安全性中的主要步骤之一。Spring 提供依赖项,即Spring Security,可帮助在 API 上建立身份验证。有很…...
设计模式中单例模式中懒汉模式的问题
设计模式中单例模式中懒汉模式的问题 今天在项目中遇到了要使用懒汉模式的问题。百度之后,发现还有很多细节是自己之前没有见过的。于是记录一下。下面是在AI助手中的说明。 单例模式的懒汉模式(Lazy Singleton)是在需要时才创建实例&#…...
【唐叔学算法】第18天:解密选择排序的双重魅力-直接选择排序与堆排序的Java实现及性能剖析
引言 在数据排序的世界里,选择排序是一类简单而直观的算法,它通过不断选取未排序部分中的最小(或最大)元素来逐步构建有序序列。今天,我们将深入探讨两种基于选择思想的排序方法——直接选择排序和堆排序,…...
力扣48.旋转图像
文章目录 一、前言二、原地旋转 一、前言 力扣48.旋转图像 这道题要求把给定矩阵旋转90度,并且不允许使用额外矩阵来完成旋转图像。 于是这道题只能使用原地旋转的方法来解决 二、原地旋转 对于一个N3的矩阵来说,只需要两次循环就可以完成了 将A1放到…...
jdk1.8新特性、jvm内存结构、垃圾回收
一、JDK 1.8 也被称为 Java 8,有许多重要的新特性: 1、Lambda 表达式: 它允许把函数作为一个方法的参数(函数作为值传递),可以用更紧凑的方式来表示匿名内部类了例如: new Thread(new Runnable() {Overr…...
MFC/C++学习系列之简单记录13
MFC/C学习系列之简单记录13 前言memsetList Control代码注意 总结 前言 今天记录一下memset和List control 的使用吧! memset memset通常在初始化变量或清空内存区域的时候使用,可以对变量设定特定的值。 使用: 头文件: C&#…...
RabbitMQ中的Topic模式
在现代分布式系统中,消息队列(Message Queue)是实现异步通信、解耦系统组件的重要工具。RabbitMQ 是一个广泛使用的开源消息代理,支持多种消息传递模式,其中 Topic 模式 是一种灵活且强大的模式,允许生产者…...
苹果手机怎么清理空间:拯救你的拥挤手机
在数字生活的海洋中,我们的苹果手机就像一艘小船,载满了照片、应用、视频和各种下载的“宝贝”。随着时间的推移,这艘小船开始变得拥挤,航行速度放缓,甚至有时候直接卡壳。苹果手机怎么清理空间?是时候学会…...
实习冲刺数据库练习-01 基础查询
原题链接:牛客网在线编程_SQL篇_非技术快速入门 数据表示例: 根据数据表示例要求我们完成以下查询: (1)获取用户信息表中所有的数据,请你取出相应结果 (2)获取用户的设备id对应的…...
GAN网络详解及涨点大全总结(源码)
(需要源码请私信或评论) GAN原理 GAN的基本原理建立在 生成模型和判别模型的博弈过程 上。这种独特的机制使得GAN能够在复杂的分布上实现高效的无监督学习。在这个过程中,生成器G和判别器D相互竞争,最终达到一种平衡状态,在此状态下,G能够产生高质量的合成样本,而D则无…...
前端关于pptxgen.js个人使用介绍
官方文档链接:Quick Start Guide | PptxGenJS git地址:https://github.com/gitbrent/PptxGenJS/ 1. 安装命令 npm install pptxgenjs --save yarn add pptxgenjs 2. 示例demo import pptxgen from "pptxgenjs"; // 引入pptxgen // 1. Create a Presenta…...
Webrtc音频模块(四) 音频采集
音频的采集还是封装在AudioDeviceWindowsCore中,相关的Core Audio API接口是下面几个: IAudioClient* _ptrClientIn IAudioCaptureClient* _ptrCaptureClient rtc::scoped_refptr<IMediaObject> _dmo rtc::scoped_refptr<IMediaBuffer> _me…...
乘积小于K的子数组
要解决“乘积小于 k 的子数组”问题,可以使用滑动窗口技术。下面是详细的步骤和思路: 初始化变量: 定义两个指针 left 和 right,都初始化为 0,用于表示窗口的左右边界。一个 product 变量初始化为 1,用于存…...
vue的ElMessage的css样式不生效
我使用elementplus,是使用的用哪个单独引入的,然后表单校验时候警告的css不生效,就是这个效果 反复看视频的引入也没发现问题,后来才知道需要这个引入 import { ElMessage } from "element-plus"; import element-pl…...
视频会议系统如何对接电话会议系统?
视频会议系统如何对接电话会议系统? 作者:开源视频会议系统BigBlueButton&BBBEasy中国区团队,Github地址:https://github.com/lihaiya/bigbluebutton 视频会议系统与电话会议系统的对接,是现代企业通信整合的重要…...
亚马逊API接口深度解析:如何高效获取商品详情与评论数据
在当今数字化时代,电商平台的数据对于商家和开发者来说至关重要。亚马逊作为全球领先的电商平台,其API接口为开发者提供了丰富的商品信息和评论数据。本文将深入探讨如何使用亚马逊API接口获取商品详情和商品评论,同时提供简洁明了的使用方法…...
1222面经
1,Kafka 如何保障顺序消费? Kafka 保障顺序消费主要通过以下几个关键机制和配置来实现: 分区策略 Kafka 将主题划分为多个分区,每个分区内的消息是天然有序的,其按照消息发送到分区的先后顺序进行存储和追加。生产者在发送消息…...
271-基于XC7V690T的12路光纤PCIe接口卡
一、板卡概述 基于XC7V690T的12路光纤PCI-E接口卡,用于实现多通道高速光纤数据接收和发送,板卡兼容PCIe 2.0和PCIe 3.0规范,利用PCI-E Switch PEX 8748实现FPGA芯片与计算机的通信,计算机与板卡接口处提供PCI-e 16速接口ÿ…...