python——正则表达式

一、简介

在 Python 中,正则表达式主要通过 re 模块实现,用于字符串的匹配、查找、替换等操作。

二、Python的re模块

使用前需要导入:

python 复制代码
import re

三、常用方法

方法 描述
re.match(pattern, string) 从字符串开头 匹配,返回第一个匹配对象,否则返回 None
re.search(pattern, string) 扫描整个字符串 ,返回第一个匹配对象,否则返回 None
re.findall(pattern, string) 返回所有匹配的子字符串列表
re.finditer(pattern, string) 返回所有匹配的迭代器(包含匹配对象)
re.sub(pattern, repl, string) 将匹配的子字符串替换为 repl
re.split(pattern, string) 按匹配模式分割字符串,返回列表

1、搜索匹配:re.search(pattern, string)

python 复制代码
text = "订单号:ABC123 金额:¥99.8"
if re.search(r'\d+\.\d+', text):  # 检查是否有小数
    print("发现金额")

2、查找所有匹配项 :re.findall(pattern, string)

python 复制代码
emails = "联系:a@x.com, b@y.cn"
print(re.findall(r'\w+@\w+\.\w+', emails))  # 输出 ['a@x.com', 'b@y.cn']

(1)正则表达式拆解 \w+@\w+\.\w+

  • \w+:匹配用户名部分

    • \w = 字母/数字/下划线(等价于 [a-zA-Z0-9_])

    • + = 至少出现1次

    • 示例:匹配 "a"、"user123"

  • @:直接匹配邮箱符号

  • \w+:匹配域名主体

    • 示例:匹配 "x"、"google"
  • \. :转义 匹配真实的点(.)

    • 注意:不加反斜杠的 . 会匹配任意字符
  • \w+:匹配顶级域名

    • 示例:匹配 "com"、"cn"

(2)匹配过程演示

以第一个邮箱 "a@x.com" 为例:

python 复制代码
原始字符串:联系:a@x.com, b@y.cn
           ↑开始匹配
           |------------------|
           匹配流程:
           \w+ → "a" 
           @   → 匹配@符号 
           \w+ → "x" 
           \.  → 匹配点 
           \w+ → "com"

3、替换文本 :re.sub(pattern, replacement, string)

python 复制代码
text = "2023-08-15"
new_text = re.sub(r'(\d{4})-(\d{2})-(\d{2})', r'\2/\3/\1', text)  # 改为 "08/15/2023"

(1) 正则表达式分解 (\d{4})-(\d{2})-(\d{2})

python

  • (\d{4}):捕获年(4位数字)

    • 示例:匹配 "2023"
  • -:匹配日期分隔符(原格式的短横线)

  • (\d{2}):捕获月(2位数字)

    • 示例:匹配 "08"
  • -:再次匹配分隔符

  • (\d{2}):捕获日(2位数字)

    • 示例:匹配 "15"

(2)分组编号:

  1. 第1组:年(\1)

  2. 第2组:月(\2)

  3. 第3组:日(\3)

(3)替换逻辑 r'\2/\3/\1'

替换字符串中的 \数字 对应正则中的分组:

  • \2 → 第2组(月)

  • \3 → 第3组(日)

  • \1 → 第1组(年)

(4)关键细节

分组顺序:括号从左到右编号,与位置无关

python 复制代码
# 错误示范:错误的分组顺序
re.sub(r'(\d{2})-(\d{2})-(\d{4})', r'\3/\1/\2', "15-08-2023")  # 正确写法

保留原格式:替换时仅调整分组顺序,不修改内容

python 复制代码
# 原始内容中的"08"会被直接引用为\2

分隔符变化 :将短横线 - 改为斜杠 /

python 复制代码
# 替换字符串中的"/"是普通字符,无需转义

**四、**核心元字符速查表

符号 含义 等价写法 示例
\d 任意数字 (0-9) [0-9] \d+ 匹配 "123"
\D 非数字字符 [^0-9] \D+ 匹配 "abc"
\w 单词字符(字母/数字/下划线) [a-zA-Z0-9_] \w+ 匹配 "user123"
\W 非单词字符 [^\w] \W+ 匹配 "@#$"
\s 空白字符(空格、换行、制表符等) [ \t\n\r\f\v] \s+ 匹配 " \t"
\S 非空白字符 [^\s] \S+ 匹配 "Hello"
. 任意字符(默认不包含换行) --- a.c 匹配 "abc" 或 "a c"
^ 脱字符 ------ re.search(r'^Hello', 'Hello World') → 匹配成功
$ 美元符 ------ re.search(r'World$', 'Hello World') → 匹配成功
[核心元字符速查表]

1、自定义字符集合

用方括号 [] 自定义匹配范围:

(1)匹配特定字符

python 复制代码
# 匹配元音字母
re.findall(r'[aeiou]', "hello")  # ['e', 'o']

# 匹配数字或小写字母
re.search(r'[0-9a-z]', "ID: A3")  # 匹配 "3"

(2)排除特定字符

在 [] 中使用 ^ 表示排除:

python 复制代码
# 匹配非数字字符
re.findall(r'[^0-9]', "R2D2")  # ['R', 'D']

(3) 组合范围

python 复制代码
# 匹配十六进制字符(0-9, A-F)
re.findall(r'[0-9A-Fa-f]', "Hex: 1aF")  # ['1', 'a', 'F']

2、特殊字符处理

(1)转义符号

匹配正则中的特殊符号(如 .、*)时,需用 \ 转义:

python 复制代码
# 匹配浮点数中的点
re.search(r'\d+\.\d+', "价格 9.99")  # 匹配 "9.99"

(2) Unicode 字符(如中文)

Python 的 re 模块默认支持 Unicode:

python 复制代码
# 匹配中文字符
re.findall(r'[\u4e00-\u9fa5]+', "Hello 你好!")  # ['你好']

五、量词控制重复次数

量词 含义 示例 行为说明
* 0次或多次 a* 匹配 "", "a", "aaa" 尽可能多匹配(贪婪模式)
+ 1次或多次 \d+ 匹配 "1", "123" 至少出现一次
? 0次或1次 colou?r 匹配 "color"/"colour" 可选匹配
{n} 精确n次 \d{4} 匹配4位数字 如年份匹配
{n,} 至少n次 \w{3,} 匹配3个以上字母数字 如密码长度验证
{n,m} n到m次 \d{2,4} 匹配2-4位数字 范围控制
[量词控制重复次数]

1、自定义字符集 []

python 复制代码
# 匹配元音字母
re.findall(r'[aeiou]', 'hello')  # ['e', 'o']

# 匹配十六进制字符(0-9, a-f)
re.search(r'[0-9a-fA-F]+', 'Color: #FF00FF')  # 匹配 "#FF00FF"

2、排除字符集 [^]

python 复制代码
# 匹配非数字字符
re.findall(r'[^0-9]', 'R2-D2')  # ['R', '-', 'D']

3、逻辑或 |

python 复制代码
# 匹配多种日期格式
pattern = r'\d{4}-\d{2}-\d{2}|\d{2}/\d{2}/\d{4}'
re.findall(pattern, '2023-08-15 或 08/15/2023')  # 匹配两者

4、捕获组 ()

python 复制代码
# 提取日期各部分
date = '2023-08-15'
match = re.search(r'(\d{4})-(\d{2})-(\d{2})', date)
print(match.groups())  # ('2023', '08', '15')

5、反向引用 \n

python 复制代码
# 查找重复单词
re.findall(r'\b(\w+)\b\s+\1\b', 'hello hello world')  # ['hello']

6、 非捕获组 (?:)

python 复制代码
# 匹配但不捕获组
re.findall(r'(?:Mr|Ms)\. (\w+)', 'Mr. Smith, Ms. Lee')  # ['Smith', 'Lee']

六、实战技巧

1、匹配手机号
python 复制代码
phone = "138-1234-5678"
match = re.search(r'1[3-9]\d-?\d{4}-?\d{4}', phone)
if match:
    print(f"找到手机号:{match.group()}")

2、提取网页链接

python 复制代码
html = '<a href="https://example.com">点击这里</a>'
links = re.findall(r'href="(https?://[^"]+)"', html)  # ['https://example.com']

3、密码强度验证

要求:8-20位,必须包含字母和数字

python 复制代码
password = "Passw0rd"
if re.fullmatch(r'(?=.*\d)(?=.*[a-zA-Z]).{8,20}', password):
    print("密码有效")

七、补充

1、在正则表达式中,使用 ^ 来匹配字符串的开头。

2、在正则表达式中,使用 $ 来匹配字符串结尾。

相关推荐
小羊没烦恼!5 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
伞伞悦读6 天前
【第38期】Python 模块与包详解:import、from、模块搜索路径、包结构和 __init__
开发语言·python
C语言小火车6 天前
C/C++ 为什么需要编译器?
开发语言·c++
霍霍的袁6 天前
【C++】map 和 set 的使用 | 从用法到底层
开发语言·c++·学习·visual studio
孙启超6 天前
【AI开发之Rust】第 11 课:智能指针与内部可变性
开发语言·后端·rust
此生决int6 天前
深入理解C++系列(20)——C++11(下)
开发语言·c++
CoderYanger6 天前
A.每日一题:835. 图像重叠
java·开发语言·程序人生·leetcode·面试·职场和发展·学习方法
伞伞悦读6 天前
【第37期】Python JSON 与配置详解:序列化、反序列化、嵌套结构和配置文件
开发语言·python·json
CCCCCCCCharlie6 天前
Linux进程控制四大核心操作
linux·开发语言
Brilliantwxx6 天前
【STM32】 SPI Flash 驱动开发实战:阻塞模式驱动 W25Q64(含工程代码)
开发语言·stm32·单片机·嵌入式硬件