Bootstrap

python之正则表达式

正则表达式(Regular Expression)是一种强大的文本匹配和处理工具,它在各种编程语言和文本编辑器中得到广泛应用。正则表达式提供了一种灵活、高效的方式来搜索、匹配、替换和提取文本数据。Python提供了re模块,它是Python正则表达式操作的标准库。下面是的Python正则表达式教程,介绍了基本的正则表达式语法和如何在Python中使用它们。

正则表达式的作用和优势

  1. 文本模式匹配:正则表达式可以用于查找特定的文本模式,比如匹配特定格式的日期、时间、电话号码、邮箱地址等。它能够精确地定义匹配规则,从而快速准确地找到符合条件的文本。
  2. 数据提取:通过正则表达式,可以方便地从文本中提取所需的信息。例如,从HTML代码中提取标签内容,从日志文件中提取关键信息等。
  3. 数据清洗和处理:正则表达式可以用于对文本数据进行清洗和处理。通过匹配指定的模式并替换、删除或修改文本内容,可以有效地清理和规范化数据。
  4. 格式验证:正则表达式可以用于验证输入的数据是否符合特定的格式要求。例如,验证邮箱地址、密码强度、身份证号码等。
  5. 快速搜索和替换:正则表达式提供了强大的搜索和替换功能,可以快速地在文本中查找和替换指定的模式。这在文本编辑器、代码编辑器和命令行工具中非常有用。
  6. 批量处理和批量操作:正则表达式可以应用于批量处理和批量操作的场景,例如批量重命名文件、批量修改文本内容等。
  7. 跨平台和通用性:正则表达式在各种编程语言和操作系统中都有支持,因此具有很好的跨平台和通用性。无论是使用Python、Java、JavaScript还是其他语言,都可以使用正则表达式进行文本处理。

正则表达式中一些基本符号

  1. .:匹配除换行符外的任意一个字符。 示例:a.b 可以匹配 “aab”、“axb”、“a@b” 等。
  2. *:匹配前面的元素零次或多次。 示例:ab*c 可以匹配 “ac”、“abc”、“abbc”、“abbbc” 等。
  3. +:匹配前面的元素一次或多次。 示例:ab+c 可以匹配 “abc”、“abbc”、“abbbc” 等,但不匹配 “ac”。
  4. ?:匹配前面的元素零次或一次。 示例:ab?c 可以匹配 “ac”、“abc”,但不匹配 “abbc”。
  5. []:定义一个字符类,匹配其中任意一个字符。 示例:[aeiou] 可以匹配任意一个小写元音字母。
  6. [^]:在字符类中使用,表示否定。匹配除了字符类中指定的字符之外的任意字符。 示例:[^0-9] 可以匹配任意一个非数字字符。
  7. ():定义一个分组,用于对模式进行分组和捕获。 示例:(ab)+ 可以匹配 “ab”、“abab”、“ababab” 等。
  8. |:在两个模式之间进行选择,匹配其中一个。 示例:cat|dog 可以匹配 “cat” 或 “dog”。
  9. \:用于转义特殊字符,或表示特殊序列。 示例:\. 可以匹配一个点字符,而不是任意字符。
  10. ^:匹配字符串的开头。 示例:^Hello 可以匹配以 “Hello” 开头的字符串。
  11. $:匹配字符串的结尾。 示例:World$ 可以匹配以 “World” 结尾的字符串。
  12. {}:定义重复次数的范围。 示例:a{2,4} 可以匹配 “aa”、“aaa”、“aaaa”,但不匹配 “a” 或 “aaaaa”。
  13. \b:匹配单词边界,即字符前后不是字母、数字或下划线。 示例:\bword\b 可以匹配 “word”,但不匹配 “words” 或 “sword”。
  14. \d:匹配任意一个数字字符,相当于[0-9]。 示例:\d{3} 可以匹配三位数字。
  15. \w:匹配任意一个字母、数字或下划线字符,相当于[a-zA-Z0-9_]。示例:\w+ 可以匹配一个或多个字母、数字或下划线字符。
  16. \s:匹配任意一个空白字符,包括空格、制表符、换行符等。 示例:Hello\sWorld 可以匹配 “Hello World” 或 “Hello\tWorld”。

常用的正则表达式

  1. 匹配数字:^\d+$ 可以匹配一个或多个数字。
  2. 匹配字母:^[a-zA-Z]+$ 可以匹配一个或多个字母。
  3. 匹配数字和字母:^[a-zA-Z0-9]+$ 可以匹配一个或多个数字和字母的组合。
  4. 匹配邮箱地址:^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$ 可以匹配常见的邮箱地址格式。
  5. 匹配URL:^(https?|ftp)://[^\s/$.?#].[^\s]*$ 可以匹配常见的URL格式。
  6. 匹配手机号码:^1[3456789]\d{9}$ 可以匹配中国大陆的手机号码格式。
  7. 匹配日期(YYYY-MM-DD):^\d{4}-\d{2}-\d{2}$ 可以匹配YYYY-MM-DD格式的日期。
  8. 匹配时间(HH:MM):^([01]\d|2[0-3]):[0-5]\d$ 可以匹配24小时制的时间格式。
  9. 匹配IP地址:^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$ 可以匹配IPv4地址。
  10. 匹配HTML标签:<(\w+)>(.*)<\/\1> 可以匹配简单的HTML标签,如<p>...</p>
  11. 匹配邮政编码:^[1-9]\d{5}$ 可以匹配6位数字的邮政编码。
  12. 匹配身份证号码:^\d{17}[\dXx]$ 可以匹配18位数字或17位数字加一个大写字母X(校验位)的身份证号码。
  13. 匹配电话号码(包括区号):^(\d{3,4}-)?\d{7,8}$ 可以匹配带有可选区号的固定电话号码。
  14. 匹配用户名:^[a-zA-Z0-9_-]{3,16}$ 可以匹配长度为3到16个字符的用户名,允许字母、数字、下划线和减号。
  15. 匹配整数:^-?\d+$ 可以匹配正整数或负整数。
  16. 匹配浮点数:^-?\d+(\.\d+)?$ 可以匹配正浮点数或负浮点数。
  17. 匹配文件路径(Windows):^[A-Za-z]:\\(?:[^\\/:*?"<>|\r\n]+\\)*[^\\/:*?"<>|\r\n]*$ 可以匹配Windows文件路径,如C:\folder\file.txt。
  18. 匹配中文字符:[\u4e00-\u9fa5] 可以匹配任意一个中文字符。
  19. 匹配空白行:^\s*$ 可以匹配只包含空白字符的行。
  20. 匹配HTML标签(非贪婪模式):<.*?> 可以匹配HTML标签,但是在遇到第一个闭合的尖括号时停止匹配。

re常用函数

1. 使用search函数进行匹配

re.search(pattern, string, flags=0):在字符串中搜索匹配正则表达式的第一个位置,并返回一个匹配对象。

import re

pattern = r"apple"
string = "I have an apple."
match = re.search(pattern, string)
if match:
    print("Match found:", match.group())
else:
    print("Match not found.")
2. 使用findall函数查找所有匹配项

re.findall(pattern, string, flags=0):在字符串中查找所有匹配正则表达式的部分,并返回一个列表。

import re

pattern = r"\d+"
string = "I have 3 apples and 5 oranges."
matches = re.findall(pattern, string)
print(matches)
3. 使用sub函数进行替换

re.sub(pattern, repl, string, count=0, flags=0):在字符串中查找匹配正则表达式的部分,并进行替换。

import re

pattern = r"apple"
string = "I have an apple."
new_string = re.sub(pattern, "orange", string)
print(new_string)
4. 使用compile函数编译正则表达式

re.compile(pattern, flags=0):编译正则表达式为模式对象,以提高执行效率和复用。

import re

pattern = re.compile(r"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b")
string = "Contact us at [email protected] or [email protected]"
matches = pattern.findall(string)
print(matches)

这些是常用的re模块函数的使用方法。通过这些函数,您可以在字符串中进行正则表达式的匹配、查找和替换操作。请记住,可以通过使用不同的标志和参数来调整匹配行为,并根据需要使用模式对象进行更复杂的操作。

常用正则表达式实例

1.匹配QQ
import re

text = "My QQ is 12345 and yours is 987654321."
qq_pattern = r"[1-9]\d{4,11}"
qq_matches = re.findall(qq_pattern, text)
print(qq_matches)  # 输出: ['12345', '987654321']
2.匹配手机号码
import re

text = "My phone number is 13812345678 and yours is 18798765432."
phone_pattern = r"1[3456789]\d{9}"
phone_matches = re.findall(phone_pattern, text)
print(phone_matches)  # 输出: ['13812345678', '18798765432']
3.匹配邮箱
import re

text = "My email is [email protected] and yours is [email protected]."
email_pattern = r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}"
email_matches = re.findall(email_pattern, text)
print(email_matches)  # 输出: ['[email protected]', '[email protected]']
4.匹配网址
import re

text = "Check out these websites: http://www.example.com, https://www.google.com, www.yahoo.com"

# 匹配网址
url_pattern = r"(http|https)://([a-zA-Z0-9.-]+\.[a-zA-Z]{2,})"
urls = re.findall(url_pattern, text)
for url in urls:
    full_url = url[0] + "://" + url[1]
    print(full_url)

# 输出:
# http://www.example.com
# https://www.google.com

提取和操作匹配结果

当使用正则表达式进行匹配时,可以通过匹配结果对象进行提取和操作。以下是一些常用的方法和属性,用于提取和操作匹配结果:

  1. group():
    • group() 方法用于获取匹配的字符串。
    • 可以传递一个可选的参数来指定要获取的捕获分组,默认为 0,表示整个匹配结果。
    • 例如,match.group(1) 可以获取第一个捕获分组的内容。
  2. groups():
    • groups() 方法返回一个包含所有捕获分组内容的元组。
    • 该方法不接受任何参数。
    • 例如,match.groups() 返回包含所有捕获分组的元组。
  3. groupdict():
    • groupdict() 方法返回一个字典,其中键是命名分组的名称,值是对应的匹配字符串。
    • 只适用于具有命名分组的正则表达式。
    • 例如,match.groupdict() 返回一个包含命名分组内容的字典。
  4. start():
    • start() 方法返回匹配的起始位置的索引。
    • 可以传递一个可选的参数来指定要获取的捕获分组的起始位置,默认为 0,表示整个匹配结果的起始位置。
    • 例如,match.start(1) 返回第一个捕获分组的起始位置。
  5. end():
    • end() 方法返回匹配的结束位置的索引。
    • 可以传递一个可选的参数来指定要获取的捕获分组的结束位置,默认为 0,表示整个匹配结果的结束位置。
    • 例如,match.end(1) 返回第一个捕获分组的结束位置。
  6. span():
    • span() 方法返回匹配的起始和结束位置的索引构成的元组。
    • 可以传递一个可选的参数来指定要获取的捕获分组的位置,默认为 0,表示整个匹配结果的位置。
    • 例如,match.span(1) 返回第一个捕获分组的起始和结束位置的索引构成的元组。

通过这些方法和属性,你可以轻松地提取匹配结果中感兴趣的部分,进行进一步的处理和操作。请注意,在使用这些方法之前,确保匹配结果不是 None,即有匹配成功的结果。

贪婪和非贪婪匹配

在正则表达式中,贪婪匹配和非贪婪匹配是指匹配模式的匹配方式。

默认情况下,正则表达式是贪婪的,也就是尽可能多地匹配字符。例如,给定正则表达式a.*b和字符串a123b456b789,贪婪匹配会尽可能匹配更多的字符,结果是整个字符串被匹配为a123b456b

然而,在某些情况下,我们可能需要非贪婪匹配,也称为最小匹配。非贪婪匹配会尽可能少地匹配字符。在正则表达式中,可以使用?来表示非贪婪匹配。对于上述例子,非贪婪匹配的正则表达式为a.*?b,结果会匹配第一个a和最近的b,即a123b

另一个常见的示例是匹配HTML标签。给定正则表达式<.*>和字符串<div>some text</div><p>another text</p>,贪婪匹配会匹配整个字符串,结果是<div>some text</div><p>another text</p>。而非贪婪匹配的正则表达式为<.*?>,结果会匹配第一个<div>

使用贪婪匹配或非贪婪匹配取决于具体的匹配需求。如果希望尽可能多地匹配字符,可以使用贪婪匹配;如果希望尽可能少地匹配字符,可以使用非贪婪匹配。需要注意的是,非贪婪匹配可能会导致匹配结果不符合预期,因此在使用时需要谨慎评估和调整。

代码实例:

字符串:<div>text1</div><div>text2</div>

正则表达式1:<div>.*</div>(贪婪匹配)

正则表达式2:<div>.*?</div>(非贪婪匹配)

import re

text = "<div>text1</div><div>text2</div>"

# 贪婪匹配示例
pattern1 = r"<div>.*</div>"
matches1 = re.findall(pattern1, text)
print("贪婪匹配结果:")
for match in matches1:
    print(match)

# 非贪婪匹配示例
pattern2 = r"<div>.*?</div>"
matches2 = re.findall(pattern2, text)
print("\n非贪婪匹配结果:")
for match in matches2:
    print(match)

运行以上代码,输出如下:

贪婪匹配结果:
<div>text1</div><div>text2</div>

非贪婪匹配结果:
<div>text1</div>

在这个示例中,我们使用re.findall()函数来找到匹配正则表达式的所有结果。pattern1使用贪婪匹配方式,导致整个字符串被匹配;而pattern2使用非贪婪匹配方式,只匹配了第一个<div>与最近的</div>之间的内容。


  • 📢博客主页:https://blog.csdn.net/qq233325332
  • 📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!
  • 📢本文由 陌北v1 原创,首发于 CSDN博客🙉
  • 📢停下休息的时候不要忘了别人还在奔跑,希望大家抓紧时间学习,全力奔赴更美好的生活✨
;