52、Python 正则表达式入门

Python 正则表达式入门

正则表达式是处理文本的强大工具,在 Python 中, re 模块提供了丰富的功能来实现正则表达式的匹配、搜索、替换等操作。本文将详细介绍 Python 中正则表达式的基本概念、语法以及如何使用 re 模块的各种方法。

1. 元字符替换

在 Python 中,可以使用 re.sub() 函数来替换文本中的特定元字符。例如:

import re
text1 = "meta characters ? and / and + and ."
result = re.sub("[/\.*?=+]+", "", text1)
print("text1:", text1)
print("替换后的结果:", result)

上述代码中, re.sub("[/\.*?=+]+", "", text1) 会匹配 text1 中出现的 [/\.*?=+] 这些元字符,并将它们替换为空字符串。

2. 字符集

在 Python 中,可以使用字符集来表示特定范围的字符。常见的字符集表示如下:
- [0-9] :匹配单个数字(0 - 9)。
- [a-z] :匹配单个小写字母(a - z)。
- [A-Z] :匹配单个大写字母(A - Z)。

以下是一些使用字符集的示例:

import re
# 匹配单个数字
pattern1 = re.compile(r"[0-9]")
print(pattern1.match("5"))  # <re.Match object; span=(0, 1), match='5'>

# 匹配两个连续的数字
pattern2 = re.compile(r"[0-9][0-9]")
print(pattern2.match("23"))  # <re.Match object; span=(0, 2), match='23'>

# 匹配三个连续的数字
pattern3 = re.compile(r"[0-9]{3}")
print(pattern3.match("789"))  # <re.Match object; span=(0, 3), match='789'>
3. “^” 和 “\” 的使用
  • “^” 的作用 :“^” 在正则表达式中的作用取决于其上下文。例如, ^[0-9] 匹配以数字开头的字符串,而 ^[^0-9] 匹配不以数字开头的字符串。
import re
# 匹配以数字开头的字符串
pattern1 = re.compile(r"^[0-9]")
print(pattern1.match("5abc"))  # <re.Match object; span=(0, 1), match='5'>

# 匹配不以数字开头的字符串
pattern2 = re.compile(r"^[^0-9]")
print(pattern2.match("abc123"))  # <re.Match object; span=(0, 1), match='a'>
  • “\” 的作用 :反斜杠 “\” 用于转义元字符的含义。例如,“.” 匹配单个字符(除了空白字符),而 “.” 匹配点号 “.” 字符。
import re
# 匹配包含 .Hello 的字符串
pattern1 = re.compile(r"\.H.*")
print(pattern1.match(".Hello"))  # <re.Match object; span=(0, 6), match='.Hello'>

# 匹配包含 Hello 的字符串
pattern2 = re.compile(r"H.*")
print(pattern2.match("Hello"))  # <re.Match object; span=(0, 5), match='Hello'>
4. 字符类

字符类是一种更简洁的表示字符集的方式。常见的字符类如下:
| 字符类 | 含义 |
| ---- | ---- |
| \d | 匹配单个数字,等同于 [0-9] |
| \w | 匹配单个字符(数字或字母),等同于 [a-zA-Z0-9_] |
| \s | 匹配单个空白字符(空格、换行符、回车符或制表符),等同于 [ \t\n\r\f\v] |
| \b | 匹配单词和非单词之间的边界 |
| \n \r \t | 分别表示换行符、回车符和制表符 |
| \ | 转义任何字符 |

以下是一些使用字符类的示例:

import re
# 匹配一个或多个数字
pattern1 = re.compile(r"\d+")
print(pattern1.match("123"))  # <re.Match object; span=(0, 3), match='123'>

# 匹配一个或多个字符
pattern2 = re.compile(r"\w+")
print(pattern2.match("abc123"))  # <re.Match object; span=(0, 6), match='abc123'>
5. re 模块的匹配方法

re 模块提供了以下几种方法来匹配和搜索正则表达式:
- match() :判断正则表达式是否在字符串的开头匹配。
- search() :在字符串中搜索正则表达式的任何匹配位置。
- findall() :查找字符串中所有匹配的子字符串,并以列表形式返回。
- finditer() :查找字符串中所有匹配的子字符串,并以迭代器形式返回。

以下是这些方法的使用示例:

import re
text = "Hello, World!"

# 使用 match() 方法
match_result = re.match(r"Hello", text)
if match_result:
    print("match() 匹配成功:", match_result.group())
else:
    print("match() 匹配失败")

# 使用 search() 方法
search_result = re.search(r"World", text)
if search_result:
    print("search() 匹配成功:", search_result.group())
else:
    print("search() 匹配失败")

# 使用 findall() 方法
findall_result = re.findall(r"\w+", text)
print("findall() 匹配结果:", findall_result)

# 使用 finditer() 方法
finditer_result = re.finditer(r"\w+", text)
for match in finditer_result:
    print("finditer() 匹配结果:", match.group())
6. 使用 re.match() 方法

re.match() 方法用于尝试在字符串的开头匹配正则表达式。其语法如下:

re.match(pattern, string, flags=0)
  • pattern :要匹配的正则表达式。
  • string :要匹配的字符串。
  • flags :可选参数,用于指定多个标志,使用按位或运算符 “|” 分隔。

以下是使用 re.match() 方法的示例:

import re
# 编译正则表达式
p = re.compile('(a(b)c)de')
# 进行匹配
m = p.match('abcde')
# 获取匹配结果
print(m.group(0))  # 'abcde'
print(m.group(1))  # 'abc'
print(m.group(2))  # 'b'

下面是一个更复杂的示例,展示了如何使用 re.match() 方法匹配不同的字符串:

import re
line1 = 'abcd123'
line2 = 'abcdefg'
# 编译正则表达式
mixed = re.compile(r"^[a-z0-9]{5,7}$")
line3 = mixed.match(line1)
line4 = mixed.match(line2)
print('line1:', line1)
print('line2:', line2)
print('line3:', line3)
print('line4:', line4)
if line4:
    print('line5:', line4.group(0))
7. re.match() 方法的选项

re.match() 方法支持各种可选修饰符,用于影响匹配的类型。常见的修饰符如下:
| 修饰符 | 含义 |
| ---- | ---- |
| re.I | 执行不区分大小写的匹配 |
| re.L | 根据当前语言环境解释单词 |
| re.M | 使 $ 匹配行的末尾,使 ^ 匹配任何行的开头 |
| re.S | 使点号 “.” 匹配任何字符(包括换行符) |
| re.U | 根据 Unicode 字符集解释字母 |

以下是使用修饰符的示例:

import re
text = "Hello, World!"
# 使用 re.I 修饰符进行不区分大小写的匹配
match_result = re.match(r"hello", text, re.I)
if match_result:
    print("使用 re.I 修饰符匹配成功:", match_result.group())
else:
    print("使用 re.I 修饰符匹配失败")
8. 使用 re.search() 方法

re.match() 方法不同, re.search() 方法可以在字符串的任何位置匹配子字符串。其语法如下:

re.search(pattern, string, flags=0)

以下是使用 re.search() 方法的示例:

import re
str = 'I want a tasty pizza'
match = re.search(r'tasty \w\w\w\w\w', str)
if match:
    print('found', match.group())
else:
    print('Nothing tasty here')

下面是一个对比 re.match() re.search() 方法的示例:

import re
text = "this is the one"
# 使用 re.search() 方法
print(re.search('this', text).span())  # (0, 4)
print(re.search('the', text).span())  # (8, 11)

# 使用 re.match() 方法
print(re.match('this', text).span())  # (0, 4)
try:
    print(re.match('the', text).span())
except AttributeError:
    print("re.match('the', text) 匹配失败")
9. 使用 findAll() 方法

re.findall() 方法用于查找字符串中所有匹配的子字符串,并以列表形式返回。以下是使用 re.findall() 方法的示例:

import re
str1 = "123456"
# 匹配一个或多个数字
matches1 = re.findall("(\d+)", str1)
print('matches1:', matches1)
# 匹配三个连续的数字
matches1 = re.findall("(\d\d\d)", str1)
print('matches1:', matches1)
# 匹配两个连续的数字
matches1 = re.findall("(\d\d)", str1)
print('matches1:', matches1)

str2 = "1a2b3c456"
# 匹配单个数字
matches2 = re.findall("(\d)", str2)
print('matches2:', matches2)
# 匹配单个数字
matches2 = re.findall("\d", str2)
print('matches2:', matches2)

str3 = "1a2b3c456"
# 匹配单个字符
matches3 = re.findall("(\w)", str3)
print('matches3:', matches3)
10. 查找字符串中的大写单词

可以使用 re.findall() 方法查找字符串中以大写字母开头的单词。以下是示例代码:

import re
str = "This Sentence contains Capitalized words"
caps = re.findall(r'[A-Z][\w\.-]+', str)
print('str: ', str)
print('caps:', caps)
11. 正则表达式的其他匹配函数

在调用 match() search() findAll() finditer() 方法后,可以对匹配对象调用其他方法。例如:

import re
# 编译正则表达式
p1 = re.compile('[a-z]+')
# 进行匹配
m1 = p1.match("hello")
# 调用匹配对象的方法
print(m1.group())  # 返回匹配的字符串
print(m1.start())  # 返回匹配的起始位置
print(m1.end())  # 返回匹配的结束位置
print(m1.span())  # 返回一个包含起始和结束位置的元组
12. 正则表达式中的分组

在正则表达式中,可以使用括号进行分组。以下是一个示例:

import re
# 编译正则表达式
p1 = re.compile('(ab)*')
# 进行匹配并获取匹配结果
print('match1:', p1.match('ababababab').group())
print('span1: ', p1.match('ababababab').span())

# 编译另一个正则表达式
p2 = re.compile('(a)b')
# 进行匹配
m2 = p2.match('ab')
# 获取匹配结果
print('match2:', m2.group(0))
print('match3:', m2.group(1))
13. 使用字符类匹配多个连续数字的字符串

可以使用正则表达式匹配包含多个连续数字的字符串。例如,匹配日期格式 MM/DD/YY 的字符串:

import re
date1 = '02/28/2013'
date2 = 'February 28, 2013'
# 匹配日期格式
pattern = re.compile(r"\d+/\d+/\d+")
print(pattern.match(date1))  # <re.Match object; span=(0, 10), match='02/28/2013'>
print(pattern.match(date2))  # None

通过以上内容,我们详细介绍了 Python 中正则表达式的基本概念、语法以及各种匹配方法的使用。希望这些内容能帮助你更好地掌握正则表达式的应用。

Python 正则表达式入门

14. 正则表达式在实际场景中的应用

正则表达式在实际开发中有广泛的应用,下面通过几个具体场景来进一步说明。

14.1 邮箱地址验证

邮箱地址有特定的格式,通常为 username@domain.com 。可以使用正则表达式来验证一个字符串是否为有效的邮箱地址。

import re

email_pattern = re.compile(r'^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$')
email1 = 'example@example.com'
email2 = 'invalid_email'

if email_pattern.match(email1):
    print(f'{email1} 是有效的邮箱地址')
else:
    print(f'{email1} 不是有效的邮箱地址')

if email_pattern.match(email2):
    print(f'{email2} 是有效的邮箱地址')
else:
    print(f'{email2} 不是有效的邮箱地址')

在上述代码中, ^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$ 这个正则表达式用于匹配邮箱地址。 ^ $ 确保整个字符串都符合该模式。

14.2 手机号码验证

手机号码也有一定的格式,以中国手机号码为例,通常是 11 位数字,且以 1 开头。

import re

phone_pattern = re.compile(r'^1[3-9]\d{9}$')
phone1 = '13800138000'
phone2 = '23456789012'

if phone_pattern.match(phone1):
    print(f'{phone1} 是有效的手机号码')
else:
    print(f'{phone1} 不是有效的手机号码')

if phone_pattern.match(phone2):
    print(f'{phone2} 是有效的手机号码')
else:
    print(f'{phone2} 不是有效的手机号码')

这里的 ^1[3-9]\d{9}$ 正则表达式, ^1 表示以 1 开头, [3-9] 表示第二位数字是 3 - 9 中的一个, \d{9} 表示后面跟着 9 位数字。

15. 正则表达式的性能优化

在处理大量数据时,正则表达式的性能可能会成为瓶颈。以下是一些性能优化的建议:

15.1 编译正则表达式

在多次使用同一个正则表达式时,应该先编译它,避免每次都进行编译操作。

import re

# 编译正则表达式
pattern = re.compile(r'\d+')
text = '123 abc 456'
matches = pattern.findall(text)
print(matches)

编译后的正则表达式对象可以重复使用,提高性能。

15.2 避免使用贪婪匹配

贪婪匹配会尽可能多地匹配字符,可能会导致性能下降。可以使用非贪婪匹配(在量词后面加上 ? )来优化。

import re

text = '<html><body><h1>Hello</h1></body></html>'
# 贪婪匹配
greedy_pattern = re.compile(r'<.*>')
greedy_matches = greedy_pattern.findall(text)
print('贪婪匹配结果:', greedy_matches)

# 非贪婪匹配
non_greedy_pattern = re.compile(r'<.*?>')
non_greedy_matches = non_greedy_pattern.findall(text)
print('非贪婪匹配结果:', non_greedy_matches)

在上述代码中,贪婪匹配会匹配从第一个 < 到最后一个 > 之间的所有内容,而非贪婪匹配会尽可能少地匹配,每次只匹配一个标签。

16. 正则表达式的流程图

下面是一个简单的流程图,展示了使用正则表达式进行文本匹配的基本流程。

graph TD;
    A[开始] --> B[定义正则表达式];
    B --> C[编译正则表达式];
    C --> D[提供待匹配的文本];
    D --> E[进行匹配操作];
    E --> F{是否匹配成功};
    F -- 是 --> G[获取匹配结果];
    F -- 否 --> H[输出未匹配信息];
    G --> I[结束];
    H --> I;
17. 总结

正则表达式是 Python 中处理文本的强大工具,通过 re 模块可以实现复杂的文本匹配、搜索和替换操作。本文详细介绍了正则表达式的基本概念,包括元字符、字符集、字符类等,以及 re 模块的各种匹配方法,如 match() search() findall() 等。同时,还通过实际场景展示了正则表达式的应用,并提供了性能优化的建议。

在实际开发中,合理运用正则表达式可以提高代码的效率和可读性,但也要注意正则表达式的复杂性,避免编写过于复杂的正则表达式导致难以维护。希望本文能帮助你更好地掌握 Python 正则表达式的使用。

方法 描述
match() 判断正则表达式是否在字符串的开头匹配
search() 在字符串中搜索正则表达式的任何匹配位置
findall() 查找字符串中所有匹配的子字符串,并以列表形式返回
finditer() 查找字符串中所有匹配的子字符串,并以迭代器形式返回

通过不断练习和实践,你将能够熟练运用正则表达式解决各种文本处理问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值