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、在正则表达式中,使用 $ 来匹配字符串结尾。

相关推荐
hsjiasb6 小时前
FreeRTOS学习(二十七)——任务栈与栈溢出检测
开发语言·stm32·学习·学习笔记·freertos
丰锋ff6 小时前
3.1 Qt事件之事件处理器
开发语言·qt
多弗朗皮卡丘7 小时前
C语言梦开始的地方7:函数
c语言·开发语言
月华路7 小时前
G1 垃圾回收:脏卡队列、记忆集与并发精化线程机制
java·开发语言
gugucoding8 小时前
47. 【Java】Java内存模型(JMM)与可见性
java·开发语言
m0_380743878 小时前
从零调用 Claude 教程
开发语言·python·node.js
起床学FPGA8 小时前
AI回答问题之后,会自动跳到最下面的问题
开发语言·javascript·ecmascript
x_x-F9 小时前
网络数据从网卡到用户态:一场基于内存所有权转移的接力赛
开发语言·网络·php
名字还没想好☜9 小时前
Java 线上内存泄漏排查实战:jmap 导堆、MAT 找 GC Roots 与四类常见泄漏
java·开发语言·jvm·内存泄漏
码匠许师傅9 小时前
【C++ 面试真题】聊聊 C++ 的多继承与虚继承
开发语言·c++·面试