【Python深入浅出】Python3正则表达式:开启高效字符串处理大门
目录
- 一、正则表达式基础入门
- 1.1 什么是正则表达式
- 1.2 正则表达式的语法规则
- 1.3 特殊字符与转义
- 二、Python 中的 re 模块
- 2.1 re 模块概述
- 2.2 常用函数与方法
- 2.2.1 re.match()
- 2.2.2 re.search()
- 2.2.3 re.findall()
- 2.2.4 re.sub()
- 2.3 修饰符(Flags)的使用
- 三、实战案例解析
- 3.1 验证邮箱地址
- 3.2 提取 IP 地址
- 3.3 替换文本内容
- 四、常见问题与解决技巧
- 4.1 贪婪匹配与非贪婪匹配
- 4.2 正则表达式的性能优化
- 4.3 处理复杂文本的技巧
- 五、总结与展望
- 5.1 总结正则表达式的重要性和应用场景
- 5.2 鼓励读者深入学习和实践
一、正则表达式基础入门
1.1 什么是正则表达式
正则表达式(Regular Expression)是一种用于匹配、搜索和处理字符串的强大工具。它定义了一种字符串的匹配模式,可以用来检查一个字符串是否符合某种规则,或者从一个字符串中提取出符合特定模式的子串。在 Python 中,正则表达式被广泛应用于文本处理、数据清洗、网页爬虫等领域。
以判断邮箱格式是否合法为例,假设我们有一个字符串test@example.com,使用正则表达式可以快速判断它是否符合邮箱的格式要求。如果没有正则表达式,我们可能需要编写复杂的代码来逐个字符地检查字符串,而使用正则表达式,只需要一行简单的代码就可以完成这个任务。
1.2 正则表达式的语法规则
正则表达式由普通字符(如字母、数字)和特殊字符(也称为元字符)组成。以下是一些常用的正则表达式语法字符:
- 点号(.):匹配除换行符以外的任意单个字符。例如,a.c可以匹配abc、a1c、a*c等字符串。
import repattern = r'a.c'
string = 'abc'
match = re.search(pattern, string)
if match:print("匹配成功")
else:print("匹配失败")
- 脱字符(^):匹配字符串的开头。例如,^hello可以匹配以hello开头的字符串,如hello world,但不能匹配world hello。
import repattern = r'^hello'
string = 'hello world'
match = re.search(pattern, string)
if match:print("匹配成功")
else:print("匹配失败")
- 美元符号($):匹配字符串的结尾。例如,world$可以匹配以world结尾的字符串,如hello world,但不能匹配world hello。
import repattern = r'world$'
string = 'hello world'
match = re.search(pattern, string)
if match:print("匹配成功")
else:print("匹配失败")
- 星号(*):匹配前面的字符零次或多次。例如,ab*可以匹配a、ab、abb、abbb等字符串。
import repattern = r'ab*'
string = 'abb'
match = re.search(pattern, string)
if match:print("匹配成功")
else:print("匹配失败")
- 加号(+):匹配前面的字符一次或多次。例如,ab+可以匹配ab、abb、abbb等字符串,但不能匹配a。
import repattern = r'ab+'
string = 'abb'
match = re.search(pattern, string)
if match:print("匹配成功")
else:print("匹配失败")
- 问号(?):匹配前面的字符零次或一次。例如,ab?可以匹配a或ab。
import repattern = r'ab?'
string = 'ab'
match = re.search(pattern, string)
if match:print("匹配成功")
else:print("匹配失败")
- 花括号({}):用于指定前面字符的出现次数。例如,a{3}表示a出现 3 次,即匹配aaa;a{2,4}表示a出现 2 到 4 次,如aa、aaa、aaaa。
import repattern = r'a{3}'
string = 'aaa'
match = re.search(pattern, string)
if match:print("匹配成功")
else:print("匹配失败")
- 方括号([]):字符集,匹配方括号中的任意一个字符。例如,[abc]可以匹配a、b或c;[0-9]表示匹配任意一个数字。
import repattern = r'[abc]'
string = 'b'
match = re.search(pattern, string)
if match:print("匹配成功")
else:print("匹配失败")
- 竖线(|):表示或的关系。例如,a|b可以匹配a或b。
import repattern = r'a|b'
string = 'b'
match = re.search(pattern, string)
if match:print("匹配成功")
else:print("匹配失败")
1.3 特殊字符与转义
在正则表达式中,有一些字符具有特殊的含义,被称为特殊字符,如^、KaTeX parse error: Undefined control sequence: \等 at position 22: …、{、}、[、]、(、)、|、\̲等̲。当我们需要匹配这些特殊字符本…符号,正则表达式应该写成$。
import repattern = r'\$100'
string = '$100'
match = re.search(pattern, string)
if match:print("匹配成功")
else:print("匹配失败")
再比如,要匹配字符串中的*符号,正则表达式应该写成*:
import repattern = r'\*'
string = '*'
match = re.search(pattern, string)
if match:print("匹配成功")
else:print("匹配失败")
二、Python 中的 re 模块
2.1 re 模块概述
在 Python 中,re模块是用于处理正则表达式的标准库。它提供了一系列丰富的函数和方法,使得我们能够方便地使用正则表达式进行字符串的匹配、搜索、替换和分割等操作。通过re模块,我们可以将复杂的字符串处理任务简化为简洁的正则表达式模式匹配,大大提高了编程效率和代码的可读性。
2.2 常用函数与方法
2.2.1 re.match()
re.match()函数用于从字符串的起始位置匹配一个模式。如果匹配成功,它将返回一个Match对象;如果匹配失败,则返回None。其函数原型为:
re.match(pattern, string, flags=0)
- pattern:表示正则表达式的模式字符串。
- string:表示要匹配的目标字符串。
- flags:可选参数,用于指定正则表达式的匹配模式,如忽略大小写、多行匹配等,默认为 0。
例如,我们要判断一个字符串是否以"Hello"开头:
import repattern = r'Hello'
string = 'Hello, World!'
match = re.match(pattern, string)
if match:print("匹配成功")
else:print("匹配失败")
在上述代码中,re.match(pattern, string)尝试从string的起始位置匹配pattern。如果string以"Hello"开头,match将是一个Match对象,否则为None。
2.2.2 re.search()
re.search()函数用于在整个字符串中搜索第一个匹配的模式。与re.match()不同,它并不要求从字符串的起始位置开始匹配。如果找到匹配项,返回一个Match对象;否则返回None。其函数原型为:
re.search(pattern, string, flags=0)
参数含义与re.match()相同。
例如,我们要在一个字符串中查找是否包含数字:
import repattern = r'\d'
string = 'I have 10 apples'
match = re.search(pattern, string)
if match:print("找到匹配的数字:", match.group())
else:print("未找到匹配的数字")
在这个例子中,re.search(pattern, string)会在整个string中搜索是否存在数字。如果找到,match.group()将返回匹配到的数字。
2.2.3 re.findall()
re.findall()函数用于查找字符串中所有(非重叠)匹配的模式,并返回一个包含所有匹配子串的列表。如果没有找到匹配项,则返回一个空列表。其函数原型为:
re.findall(pattern, string, flags=0)
参数含义与前面两个函数相同。
例如,我们要提取一个字符串中的所有单词:
import repattern = r'\w+'
string = 'Hello, World! How are you?'
words = re.findall(pattern, string)
print("提取到的单词:", words)
在上述代码中,re.findall(pattern, string)会查找string中所有的单词,并将它们存储在words列表中。
2.2.4 re.sub()
re.sub()函数用于使用指定的替换字符串替换字符串中所有匹配的模式。其函数原型为:
re.sub(pattern, repl, string, count=0, flags=0)
- pattern:表示正则表达式的模式字符串。
- repl:表示替换的字符串或一个函数。
- string:表示要处理的目标字符串。
- count:可选参数,表示最多替换的次数,默认为 0,表示替换所有匹配项。
- flags:可选参数,用于指定正则表达式的匹配模式,默认为 0。
例如,我们要将一个字符串中的所有数字替换为"X":
import repattern = r'\d'
string = 'I have 10 apples and 5 oranges'
new_string = re.sub(pattern, 'X', string)
print("替换后的字符串:", new_string)
在这个例子中,re.sub(pattern, ‘X’, string)会将string中的所有数字替换为"X",并返回替换后的新字符串。
2.3 修饰符(Flags)的使用
正则表达式修饰符可以改变正则表达式的匹配行为,使我们能够更灵活地进行字符串匹配。以下是一些常用的修饰符:
- re.IGNORECASE(或 re.I):忽略大小写匹配。例如,要匹配字符串中的"hello",不区分大小写:
import repattern = r'hello'
string1 = 'Hello, World!'
string2 = 'hello, World!'
match1 = re.search(pattern, string1, re.IGNORECASE)
match2 = re.search(pattern, string2, re.IGNORECASE)
if match1:print("在string1中找到匹配项")
if match2:print("在string2中找到匹配项")
- re.MULTILINE(或 re.M):多行匹配模式。在这种模式下,^和$将匹配每一行的开头和结尾,而不仅仅是整个字符串的开头和结尾。例如,要匹配每一行的开头的数字:
import repattern = r'^\d'
string = '1 line1\n2 line2\n3 line3'
matches = re.findall(pattern, string, re.MULTILINE)
print("匹配到的数字:", matches)
- re.DOTALL(或 re.S):使点号(.)匹配包括换行符在内的所有字符。默认情况下,点号不匹配换行符。例如,要匹配包含换行符的字符串:
import repattern = r'.+'
string = 'line1\nline2'
match1 = re.search(pattern, string)
match2 = re.search(pattern, string, re.DOTALL)
if match1:print("match1匹配到的内容:", match1.group())
if match2:print("match2匹配到的内容:", match2.group())
在上述代码中,match1由于没有使用re.DOTALL修饰符,只能匹配到"line1";而match2使用了re.DOTALL修饰符,可以匹配到"line1\nline2"。
三、实战案例解析
3.1 验证邮箱地址
在实际应用中,经常需要验证用户输入的邮箱地址是否合法。我们可以使用正则表达式来实现这一功能。以下是一个验证邮箱地址的 Python 函数:
import redef validate_email(email):pattern = r'^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$'if re.match(pattern, email):return Trueelse:return False# 测试邮箱
email1 = "test@example.com"
email2 = "test.example.com"
print(validate_email(email1))
print(validate_email(email2))
在上述代码中,validate_email函数接收一个字符串参数email,然后使用re.match函数来检查该字符串是否符合邮箱地址的正则表达式模式。
这个邮箱地址的正则表达式模式^[a-zA-Z0-9_.±]+@[a-zA-Z0-9-]+.[a-zA-Z0-9-.]+$可以这样分析:
- ^:表示匹配字符串的开头。
- [a-zA-Z0-9_.±]+:表示用户名部分,它可以包含字母、数字、下划线、点、加号和减号,并且至少出现一次。
- @:匹配邮箱地址中的@符号。
- [a-zA-Z0-9-]+:表示域名的主体部分,由字母、数字和减号组成,至少出现一次。
- .:匹配实际的点号,因为点号在正则表达式中有特殊含义,所以需要转义。
- [a-zA-Z0-9-.]+:表示顶级域名部分,例如.com、.net、.org等,它可以包含字母、数字、点和减号,至少出现一次。
- $:表示匹配字符串的结尾。
3.2 提取 IP 地址
在网络编程和日志分析等场景中,经常需要从文本中提取 IP 地址。IP 地址由 4 个 0 - 255 之间的数字组成,每个数字之间用点号分隔。以下是使用正则表达式提取 IP 地址的示例代码:
import redef extract_ip(text):pattern = r'\b(?:\d{1,3}\.){3}\d{1,3}\b'matches = re.findall(pattern, text)return matchestext = "我的IP地址是192.168.1.1,另一台设备的IP是10.0.0.1"
ips = extract_ip(text)
print(ips)
在这个例子中,extract_ip函数使用re.findall函数查找文本中所有符合 IP 地址模式的字符串。
正则表达式\b(?:\d{1,3}.){3}\d{1,3}\b解释如下:
- \b:表示单词边界,确保匹配的是完整的 IP 地址,而不是其他字符串中包含的类似数字组合。
- (?:\d{1,3}.):这是一个非捕获组,表示匹配 1 到 3 位数字,后面跟着一个点号。?:表示这是一个非捕获组,不会在匹配结果中单独保存这部分内容。
{3}:表示前面的非捕获组重复 3 次,即匹配 3 个由 1 到 3 位数字和一个点号组成的部分。 - \d{1,3}:最后再匹配一个 1 到 3 位数字,完成 IP 地址的最后一部分。
- \b:再次使用单词边界,确保 IP 地址的结束。
3.3 替换文本内容
在文本处理中,有时需要替换文本中的敏感词,以保护用户隐私或符合某些规定。我们可以使用re.sub()函数来实现这一功能。以下是一个替换敏感词的示例:
import redef replace_sensitive_words(text, sensitive_words, replacement='***'):pattern = re.compile(r'\b({})\b'.format('|'.join(map(re.escape, sensitive_words))), re.IGNORECASE)replaced_text = pattern.sub(replacement, text)return replaced_textsensitive_words = ['敏感词1', '敏感词2', '敏感词3']
text = '这是一段包含敏感词1和敏感词2的文本。'
new_text = replace_sensitive_words(text, sensitive_words)
print(new_text)
在上述代码中,replace_sensitive_words函数接受三个参数:待处理的文本text、敏感词列表sensitive_words和替换字符串replacement(默认为***)。
首先,使用re.compile函数编译正则表达式模式。
r’\b({})\b’.format(‘|’.join(map(re.escape, sensitive_words)))这个模式的含义是:
- \b:表示单词边界,确保只匹配完整的单词。
- {}:通过format方法将|连接的敏感词列表插入进来,|表示或的关系,即匹配列表中的任意一个敏感词。
re.escape函数用于转义敏感词中的特殊字符,防止它们在正则表达式中产生歧义。 - re.IGNORECASE:表示忽略大小写进行匹配。
然后,使用编译后的模式调用sub方法,将文本中的敏感词替换为指定的替换字符串,并返回替换后的文本。
在实际应用中,可能需要考虑更多复杂的情况,比如多语言支持、部分匹配等。例如,如果要支持部分匹配敏感词,可以去掉单词边界\b,但这样可能会导致误匹配,需要根据具体需求进行权衡和调整 。
四、常见问题与解决技巧
4.1 贪婪匹配与非贪婪匹配
在正则表达式中,匹配模式分为贪婪匹配和非贪婪匹配。贪婪匹配是指在满足匹配条件的情况下,尽可能多地匹配字符。例如,使用正则表达式a.*b匹配字符串aabab时,它会匹配整个aabab,因为.*会尽可能多地匹配字符,直到遇到最后一个b。这是 Python 正则表达式的默认匹配模式。
import retext = "aabab"
pattern = r"a.*b"
match = re.search(pattern, text)
if match:print("贪婪匹配结果:", match.group())
上述代码中,re.search(pattern, text)使用贪婪匹配模式,a.*b会匹配从第一个a到最后一个b之间的所有字符,所以输出结果为aabab。
非贪婪匹配则相反,它会在满足匹配条件的情况下,尽可能少地匹配字符。在 Python 中,通过在量词(如*、+、?、{n,m})后面添加?来实现非贪婪匹配。
例如,使用正则表达式a.?b匹配字符串aabab时,它只会匹配aab,因为.?会尽可能少地匹配字符,一旦遇到第一个b就停止匹配。
import retext = "aabab"
pattern = r"a.*?b"
match = re.search(pattern, text)
if match:print("非贪婪匹配结果:", match.group())
在这段代码中,a.?b使用了非贪婪匹配模式,.?会匹配尽可能少的字符,直到遇到第一个b,所以输出结果为aab。
4.2 正则表达式的性能优化
在使用正则表达式时,性能是一个需要考虑的重要因素。复杂的正则表达式可能会导致性能下降,特别是在处理大量文本时。以下是一些优化正则表达式性能的建议:
- 避免不必要的分组:分组在正则表达式中用于提取特定的子串或改变量词的作用范围。但如果不需要提取子串,尽量避免使用捕获组(),因为捕获组会增加额外的处理开销。可以使用非捕获组(?:…),它不会存储匹配的内容,从而提高性能。例如,要匹配一个数字后跟一个字母的模式,如果不需要提取数字和字母,使用(?:\d[a-zA-Z])比(\d[a-zA-Z])性能更好。
import retext = "1a 2b 3c"
# 使用捕获组
pattern1 = r"(\d[a-zA-Z])"
matches1 = re.findall(pattern1, text)
print("使用捕获组的结果:", matches1)# 使用非捕获组
pattern2 = r"(?:\d[a-zA-Z])"
matches2 = re.findall(pattern2, text)
print("使用非捕获组的结果:", matches2)
在上述代码中,虽然两种方式都能匹配到目标字符串,但使用非捕获组的pattern2在性能上更优,因为它不需要存储匹配的子串。
- 简化模式:尽量使用简单的正则表达式模式,避免使用过于复杂的嵌套结构和过多的分支。复杂的模式会增加匹配的时间和计算资源。例如,要匹配一个可能是数字或者字母的字符串,可以使用[\dA-Za-z]+,而不是(\d+)|([A-Za-z]+)。
import retext = "123abc"
# 复杂模式
pattern1 = r"(\d+)|([A-Za-z]+)"
matches1 = re.findall(pattern1, text)
print("复杂模式的结果:", matches1)# 简化模式
pattern2 = r"[\dA-Za-z]+"
matches2 = re.findall(pattern2, text)
print("简化模式的结果:", matches2)
这里,pattern2的模式更简洁,性能也更好,pattern1使用了分支结构,增加了匹配的复杂性。
- 预编译正则表达式:如果需要多次使用同一个正则表达式,可以使用re.compile()函数将其预编译成一个正则表达式对象。这样可以避免每次使用时都进行编译,提高效率。例如:
import re# 预编译正则表达式
pattern = re.compile(r'\d+')
text1 = "I have 10 apples"
text2 = "There are 5 oranges"
match1 = pattern.search(text1)
match2 = pattern.search(text2)
if match1:print("在text1中找到:", match1.group())
if match2:print("在text2中找到:", match2.group())
在这个例子中,re.compile(r’\d+')将正则表达式预编译成pattern对象,后续对text1和text2的匹配都使用这个对象,减少了重复编译的开销。
4.3 处理复杂文本的技巧
在处理复杂文本时,构建有效的正则表达式可能具有挑战性。以下是一些实用的技巧:
- 逐步构建:不要试图一次性写出复杂的正则表达式。可以先从简单的模式开始,逐步添加条件和细节。例如,要解析一个复杂的日期时间格式YYYY - MM - DD HH:MM:SS,可以先匹配年份\d{4},然后逐步添加月份、日期、小时、分钟和秒的匹配。
import re# 先匹配年份
pattern_year = r'\d{4}'
text = "2024-01-01 12:00:00"
match_year = re.search(pattern_year, text)
if match_year:print("匹配到的年份:", match_year.group())# 逐步添加匹配月份和日期
pattern_date = r'\d{4}-\d{2}-\d{2}'
match_date = re.search(pattern_date, text)
if match_date:print("匹配到的日期:", match_date.group())# 最终完整的模式
pattern_datetime = r'\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}'
match_datetime = re.search(pattern_datetime, text)
if match_datetime:print("匹配到的日期时间:", match_datetime.group())
通过这种逐步构建的方式,可以更容易地调试和优化正则表达式。
- 使用注释:对于复杂的正则表达式,可以使用注释来解释各个部分的含义,提高代码的可读性。在 Python 中,可以使用re.VERBOSE修饰符(或re.X)来实现这一点。例如:
import repattern = re.compile(r"""^ # 匹配字符串开头\d{4} # 匹配4位年份- # 匹配 - 符号\d{2} # 匹配2位月份- # 匹配 - 符号\d{2} # 匹配2位日期\s # 匹配空白字符\d{2} # 匹配2位小时: # 匹配 : 符号\d{2} # 匹配2位分钟: # 匹配 : 符号\d{2} # 匹配2位秒$ # 匹配字符串结尾
""", re.VERBOSE)text = "2024-01-01 12:00:00"
match = pattern.search(text)
if match:print("匹配到的日期时间:", match.group())
在上述代码中,re.VERBOSE修饰符允许在正则表达式中使用注释和空白字符,使模式更易于理解。
以解析 HTML 或 XML 文本为例,虽然正则表达式不是处理这类结构化文本的最佳选择(通常建议使用专门的解析库,如BeautifulSoup处理 HTML,ElementTree处理 XML),但在某些简单情况下,也可以使用正则表达式进行基本的文本提取。比如提取 HTML 中的所有链接:
import rehtml = '<a href="https://example.com">Example</a><a href="https://another.com">Another</a>'
pattern = r'<a href="([^"]+)">'
matches = re.findall(pattern, html)
print("提取到的链接:", matches)
在这个例子中,r’<a href=“([“]+)”>'这个正则表达式用于匹配<a>标签中的href属性值。([”]+)表示匹配除双引号以外的任意字符,尽可能多地匹配,从而提取出链接地址。但需要注意的是,这种方法对于复杂的 HTML 结构可能会出现匹配不准确的情况 。
五、总结与展望
5.1 总结正则表达式的重要性和应用场景
正则表达式作为 Python 编程中强大的文本处理工具,其重要性不言而喻。在字符串处理领域,它就像是一把瑞士军刀,能够高效地完成各种复杂任务。无论是简单的字符串匹配,还是复杂的文本模式识别,正则表达式都能应对自如。通过定义灵活的匹配模式,我们可以轻松地从海量文本数据中筛选出符合特定规则的信息,极大地提高了数据处理的效率和准确性。
在数据验证方面,正则表达式发挥着关键作用。在用户注册、登录等场景中,需要对用户输入的邮箱地址、手机号码、密码等信息进行格式验证。使用正则表达式可以快速准确地判断用户输入是否符合要求,确保数据的有效性和一致性。例如,验证邮箱地址时,通过编写合适的正则表达式,可以准确识别出合法的邮箱格式,避免因用户输入错误格式的邮箱而导致后续业务流程出现问题。
文本提取是正则表达式的又一重要应用场景。在网页爬虫、数据分析等任务中,经常需要从网页源码、日志文件等文本中提取特定的数据。比如,从网页中提取所有的链接、图片地址,或者从日志文件中提取关键的事件信息等。利用正则表达式,我们可以根据数据的特征定义匹配模式,精准地提取出所需的数据,为后续的数据分析和处理提供基础。
5.2 鼓励读者深入学习和实践
正则表达式的世界丰富多彩,还有许多高级特性等待着读者去探索。例如反向引用,它允许我们在正则表达式中引用之前捕获的分组内容,这在处理一些需要重复匹配或替换特定模式的场景中非常有用。比如,将字符串中的单词进行反转,或者匹配成对出现的标签等。零宽断言则是另一个强大的特性,它可以在不匹配实际字符的情况下,对字符串的位置进行断言,从而实现更复杂的模式匹配。比如,查找某个单词之前或之后的特定字符序列,而不包含该单词本身。
为了更好地掌握正则表达式,建议读者通过实际项目进行不断的实践。可以尝试参与一些开源项目中的文本处理模块,或者自己构建一些小型的文本处理工具,如简单的日志分析器、文本清洗工具等。在实践过程中,遇到问题时多查阅相关文档和资料,与其他开发者交流经验,不断积累解决问题的技巧和方法。只有通过大量的实践,才能真正熟练掌握正则表达式的应用,将其灵活运用到各种实际场景中,提升自己的编程能力和解决问题的能力 。
相关文章:

【Python深入浅出】Python3正则表达式:开启高效字符串处理大门
目录 一、正则表达式基础入门1.1 什么是正则表达式1.2 正则表达式的语法规则1.3 特殊字符与转义 二、Python 中的 re 模块2.1 re 模块概述2.2 常用函数与方法2.2.1 re.match()2.2.2 re.search()2.2.3 re.findall()2.2.4 re.sub() 2.3 修饰符(Flags)的使用…...

Vue.js Vue CLI 安装与使用
Vue.js Vue CLI 安装与使用 今天我们来聊聊 Vue CLI 的安装与使用。对于开发 Vue 应用来说,Vue CLI 是一个非常强大的工具,它能帮助你快速创建项目脚手架、配置开发环境、自动化构建流程,从而大大提高开发效率。下面我就和大家一步一步地讲解…...

科技的尽头:在有限与永恒的夹缝中寻找文明的真谛
当人类用燧石点燃第一簇文明之火时,科技发展的齿轮便已开始转动。这个从原始工具到量子计算机的进化历程,既是人类突破生物局限的史诗,也是文明不断自我解构与重构的哲学叙事。站在人工智能与基因编辑并行的时代节点,"科技尽…...

【牛客】动态规划专题一:斐波那契数列
文章目录 DP1 斐波那契数列法1:递归法2:动态规划法3:优化空间复杂度 2.分割连接字符串3. 给定一个字符串s和一组单词dict,在s中添加空格将s变成一个句子 DP1 斐波那契数列 法1:递归 // 递归 #include <iostream>…...

java8、9新特性
JAVA8 Lambda 表达式 (parameters) -> expression 或 (parameters) ->{ statements; } 提供了一种更为简洁的语法,尤其适用于函数式接口。相比于传统的匿名内部类,Lambda 表达式使得代码更为紧凑,减少了样板代码的编写。 它允许将函…...

作业:zuoye
1.闹钟(错的) #include "widget.h" #include "ui_widget.h" #include <QMessageBox>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);// 初始化定时器objTimer new QTimer(th…...

redis底层数据结构——链表
文章目录 定义内部实现总结 定义 链表提供了高效的节点重排能力,以及顺序性的节点访间方式,并且可以通过增删节点来灵活地调整链表的长度。 作为一种常用数据结构,链表内置在很多高级的编程语言里面,因为Redis使用的C语言并没有…...

问题解决 4S 法
在深入研读《像高手一样解决问题》的第二章后,犹如打开了一扇通往高效问题解决领域的新大门,其中所阐述的问题解决 4S 法,更是给人以拨云见日之感。 一、陈述(State):明确问题本质 这是问题解决的起始点&…...

SQL-leetcode—1407. 排名靠前的旅行者
1407. 排名靠前的旅行者 表:Users ---------------------- | Column Name | Type | ---------------------- | id | int | | name | varchar | ---------------------- id 是该表中具有唯一值的列。 name 是用户名字。 表:Rides -------------------…...

机器学习(李宏毅)——Transformer
一、前言 本文章作为学习2023年《李宏毅机器学习课程》的笔记,感谢台湾大学李宏毅教授的课程,respect!!! 读这篇文章必须先了解self-attention,可参阅我上一篇。 二、大纲 Transformer问世原理剖析模型训…...

React进阶之React状态管理CRA
React状态管理&CRA 状态管理理论讲解案例 context 上下文结合状态来维护todoListindex.jsApp.jsTaskList.jsTasksContext.jsAddTask.js Escape 脱围机制refforwardRef(不建议使用) CRA 状态管理 理论讲解 如何针对 effect -> 对action的触发 -&…...

攻克AWS认证机器学习工程师(AWS Certified Machine Learning Engineer) - 助理级别认证:我的成功路线图
引言 当我决定考取AWS认证机器学习工程师 - 助理(AWS Certified Machine Learning Engineer — Associate)级别证书时,我就预料到这将是一段充满挑战但回报颇丰的旅程。跟你说吧,它在这两方面都没让我失望。这项考试面向的是不仅理解机器学习原理,还对AWS生态系统有扎实基…...

前端开发环境
vscde nrm 切换源管理 nvm 切换node版本工具 nodemon node运行js文件热更新 pxcook 易用的自动标注工具, 生成前端代码, 设计研发协作利器,比PS轻量 TypeScript 安装tsc 它的作用就是将ts文件编译为js文件 npm i typescript -g 输入tsc -v能够看到东西,就说明好了 …...

Web自动化测试—测试用例流程设计
🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 一、测试用例通用结构回顾 1.1、现有测试用例存在的问题 可维护性差可读性差稳定性差 1.2、用例结构设计 测试用例的编排测试用例的项目结构 1.3、自动化测试…...

HTML全局属性与Meta元信息详解:优化网页的灵魂
目录 前言 一、HTML中的全局属性 常用的全局属性 二、Meta元信息标签:网页背后的重要配置 常用的Meta标签 三、Meta元信息的进阶使用 总结 前言 在HTML开发中,有一些属性和标签是全局性的,能够影响网页的多个方面,比如页面的…...

day001 折半查找/二分查找
day001 折半查找/二分查找 适用场景顺序表或者顺序数组 时间复杂度:log2N 算法思路 pre: 下限为0,上限为数组长度-1, 下限小于等于上限进行循环 if 比较目标值和中间值,if 大于: 则下限中间值索引1else: 小于: 则上限中间值索…...

Linux 资源监控:优化与跟踪系统性能
在 Evoxt,我们深知有效的 Linux 资源监控对于优化服务器性能至关重要。本指南将介绍关键工具和策略,帮助您监控 CPU、内存、磁盘和网络使用情况,确保您的 Linux 系统始终保持高效运行。 实时系统监控 使用 top(交互式系统监控&am…...

java安全中的类加载
java安全中的类加载 提前声明: 本文所涉及的内容仅供参考与教育目的,旨在普及网络安全相关知识。其内容不代表任何机构、组织或个人的权威建议,亦不构成具体的操作指南或法律依据。作者及发布平台对因使用本文信息直接或间接引发的任何风险、损失或法律纠…...

Node.js调用DeepSeek Api 实现本地智能聊天的简单应用
在人工智能快速发展的今天,如何快速构建一个智能对话应用成为了开发者们普遍关注的话题。本文将为大家介绍一个基于Node.js的命令行聊天应用,它通过调用硅基流动(SiliconFlow)的API接口,实现了与DeepSeek模型的智能对话…...

分布式服务框架 如何设计一个更合理的协议
1、概述 前面我们聊了如何设计一款分布式服务框架的问题,并且编码实现了一个简单的分布式服务框架 cheese, 目前 cheese 基本具备分布式服务框架的基本功能。后面我们又引入了缓存机制,以及使用Socket替代了最开始的 RestTemplate。并且还学习了网络相关…...

Unity使用iTextSharp导出PDF-02基础结构及设置中文字体
基础结构 1.创建一个Document对象 2.使用PdfWriter创建PDF文档 3.打开文档 4.添加内容,调用文档Add方法添加内容时,内容写入到输出流中 5.关闭文档 using UnityEngine; using iTextSharp.text; using System.IO; using iTextSharp.text.pdf; using Sys…...

Kafka因文件句柄数过多导致挂掉的排查与解决
一、问题现象 在k8s集群中部署了多个服务,包括Kafka、TDengine集群和Java等。这些服务使用NFS作为持久化存储方案。最近遇到了一个问题:Kafka频繁报错并最终挂掉。错误日志如下: 2025-02-09T09:39:07,022] INF0 [LogLoader partition__cons…...

【LeetCode Hot100 多维动态规划】最小路径和、最长回文子串、最长公共子序列、编辑距离
多维动态规划 机器人路径问题思路代码实现 最小路径和问题动态规划思路状态转移方程边界条件 代码实现 最长回文子串思路代码实现 最长公共子序列(LCS)题目描述解决方案 —— 动态规划1. 状态定义2. 状态转移方程3. 初始化4. 代码实现 编辑距离ÿ…...

PRC框架-Dubbo
RPC框架 RPC(Remote Procedure Call,远程过程调用)框架是一种允许客户端通过网络调用服务器端程序的技术。以下是常见的RPC框架及其特点: 1. 基于HTTP/REST的RPC框架 特点:简单易用,与Web开发无缝集成&am…...

智能检测摄像头模块在客流统计中的应用
工作原理 基于视频分析技术:智能检测摄像头模块通过捕捉监控区域内的视频画面,运用图像识别算法对视频中的人体进行检测、跟踪和分析。可以识别出人体的轮廓、姿态等特征,进而区分不同的个体,实现对客流的统计。 基于红外感应技…...

[LLM面试题] 指示微调(Prompt-tuning)与 Prefix-tuning区别
一、提示调整(Prompt Tuning) Prompt Tuning是一种通过改变输入提示语(input prompt)以获得更优模型效果的技术。举个例子,如果我们想将一条英语句子翻译成德语,可以采用多种不同的方式向模型提问,如下图所示…...

【CubeMX+STM32】SD卡 U盘文件系统 USB+FATFS
本篇,将使用CubeMXKeil, 创建一个 USBTF卡存储FatFS 的虚拟U盘读写工程。 目录 一、简述 二、CubeMX 配置 SDIO DMA FatFs USB 三、Keil 编辑代码 四、实验效果 串口助手,实现效果: U盘,识别效果: 一、简述 上…...

在JVM的栈(虚拟机栈)中,除了栈帧(Stack Frame)还有什么?
在JVM的栈(虚拟机栈)中,除了栈帧(Stack Frame),还有其他一些与方法调用相关的重要信息。栈的主要作用是存储方法调用的执行过程中的上下文信息,栈帧是其中最关键的组成部分。 栈的组成 栈帧&am…...

# 解析Excel文件:处理Excel xlsx file not supported错误 [特殊字符]
解析Excel文件:处理Excel xlsx file not supported错误 🧩 嘿,数据分析的小伙伴们!👋 我知道在处理Excel文件的时候,很多人可能会遇到这样一个错误:Excel xlsx file not supported。别担心&…...

图片下载不下来?即便点了另存为也无法下载?两种方法教你百分之百下载下来
前言,我要讲的是网站没有禁鼠标右键,可以右键,也可以打开控制台,图片也不用付费这种。 一、用鼠标按住图片直接往桌面拖动,也可以打开开发者工具,在里面往外拖。 二、这个方法很有意思,在电脑的…...