Python3入门指南Python语言的特点和实际应用Python3环境搭建配置VSCode进行Python开发Python基础语法Python变量与数据类型Python数据类型转换Python解释器使用Python注释使用Python运算符Python数字类型Python字符串操作Python列表操作Python元组使用Python字典使用Python集合使用Python条件控制详解Python循环语句详解Python编程入门实践Python推导式详解Python迭代器和生成器Python with语句详解Python函数详解Python lambda(匿名函数)Python装饰器Python数据结构Python模块和包使用Python中__name__和__main__的用法Python输入输出:从基础到文件操作Python文件操作Python OS模块使用Python错误和异常处理Python面向对象编程Python命名空间和作用域Python虚拟环境:venv详细教程Python类型注解Python标准库常用模块Python正则表达式Python CGI编程Python MySQL(mysql-connector驱动)Python MySQL(PyMySQL驱动)Python网络编程Python发送邮件Python多线程编程Python XML解析Python JSON解析Python日期和时间处理Python操作MongoDBPython urllib库使用Python uWSGI 安装与配置Python pip包管理工具Python operator模块Python math模块Python requests模块HTTP请求Python random模块Python OpenAI库Python AI绘画制作Python statistics模块Python hashlib模块:哈希加密Python量化交易Python pyecharts数据可视化Python Selenium网页自动化Python BeautifulSoup网页数据提取Python Scrapy爬虫框架Python Markdown转HTMLPython sys模块Python Pickle模块:数据存储Python subprocess模块Python queue队列模块Python StringIO内存文件操作Python logging日志记录Python datetime日期时间处理Python re正则表达式Python csv表格数据处理Python threading 多线程编程Python asyncio 异步编程Python PyQt 图形界面开发Python 应用方向和常用库框架

Python正则表达式

正则表达式是一种强大的文本处理工具,它能帮助我们快速检查、查找和替换文本内容。在Python中,我们使用re模块来处理正则表达式。


正则表达式基础

正则表达式就像是文本的"搜索模式"。比如你想在一篇文章中找出所有的电子邮箱,或者验证用户输入的手机号格式是否正确,正则表达式都能帮上忙。


re模块常用函数

re.match() - 从开头匹配

re.match()只检查字符串的开头是否符合模式。

import re

# 检查字符串是否以"Hello"开头
result = re.match(r'Hello', 'Hello world!')
if result:
    print("匹配成功:", result.group())
else:
    print("匹配失败")

# 输出:匹配成功: Hello

# 这个会失败,因为不是从开头匹配
result2 = re.match(r'world', 'Hello world!')
print(result2)  # 输出:None

re.search() - 搜索整个字符串

re.search()会在整个字符串中搜索第一个匹配的位置。

import re

# 在字符串中搜索数字
text = "我的电话是13800138000"
result = re.search(r'\d+', text)
if result:
    print("找到数字:", result.group())  # 输出:找到数字: 13800138000

# 搜索邮箱地址
text = "联系邮箱:test@fly63.com"
result = re.search(r'\w+@\w+\.\w+', text)
if result:
    print("找到邮箱:", result.group())  # 输出:找到邮箱:test@fly63.com

match和search的区别

import re

text = "Python编程学习"

# match只在开头匹配
match_result = re.match(r'编程', text)
print("match结果:", match_result)  # None

# search在整个字符串搜索
search_result = re.search(r'编程', text)
print("search结果:", search_result.group())  # 编程


实际应用示例

提取信息

import re

# 从文本中提取所有数字
text = "今天气温25度,明天气温28度,后天气温26度"
numbers = re.findall(r'\d+', text)
print("所有温度:", numbers)  # 输出:['25', '28', '26']

# 提取日期
text = "会议时间:2024-01-15,地点:北京"
date = re.search(r'\d{4}-\d{2}-\d{2}', text)
if date:
    print("会议日期:", date.group())  # 输出:会议日期: 2024-01-15

验证数据格式

import re

def validate_phone(phone):
    """验证手机号格式"""
    pattern = r'^1[3-9]\d{9}$'
    if re.match(pattern, phone):
        return True
    return False

def validate_email(email):
    """验证邮箱格式"""
    pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
    if re.match(pattern, email):
        return True
    return False

# 测试
print("手机号验证:")
print("13800138000:", validate_phone("13800138000"))  # True
print("12345678901:", validate_phone("12345678901"))  # False

print("\n邮箱验证:")
print("test@fly63.com:", validate_email("test@fly63.com"))  # True
print("invalid-email:", validate_email("invalid-email"))    # False


文本替换和清理

re.sub() - 替换文本

import re

# 隐藏手机号中间四位
phone = "用户手机:13800138000"
hidden_phone = re.sub(r'(\d{3})\d{4}(\d{4})', r'\1****\2', phone)
print(hidden_phone)  # 输出:用户手机:138****8000

# 清理文本中的html标签
html_text = "<p>这是一个<strong>测试</strong>文本</p>"
clean_text = re.sub(r'<[^>]+>', '', html_text)
print(clean_text)  # 输出:这是一个测试文本

# 统一日期格式
dates = "2024/01/15 和 2024-01-20"
uniform_dates = re.sub(r'(\d{4})/(\d{2})/(\d{2})', r'\1-\2-\3', dates)
print(uniform_dates)  # 输出:2024-01-15 和 2024-01-20

复杂的替换函数

import re

def convert_to_uppercase(match):
    """将匹配的文本转为大写"""
    return match.group().upper()

text = "hello world, python programming"
result = re.sub(r'\b\w+\b', convert_to_uppercase, text)
print(result)  # 输出:HELLO WORLD, PYTHON PROGRAMMING


分组提取

分组让我们能提取匹配的特定部分。

import re

# 提取姓名和年龄
text = "姓名:张三,年龄:25;姓名:李四,年龄:30"
pattern = r'姓名:(\w+),年龄:(\d+)'

matches = re.findall(pattern, text)
for name, age in matches:
    print(f"姓名:{name}, 年龄:{age}")
# 输出:
# 姓名:张三, 年龄:25
# 姓名:李四, 年龄:30

# 使用search提取分组
text = "出生日期:1990-05-15"
match = re.search(r'(\d{4})-(\d{2})-(\d{2})', text)
if match:
    year, month, day = match.groups()
    print(f"年:{year}, 月:{month}, 日:{day}")  # 输出:年:1990, 月:05, 日:15


编译正则表达式

如果需要多次使用同一个模式,可以先编译它,这样效率更高。

import re

# 编译正则表达式
phone_pattern = re.compile(r'1[3-9]\d{9}')
email_pattern = re.compile(r'\w+@\w+\.\w+')

# 重复使用编译后的模式
texts = [
    "电话13800138000,邮箱test@fly63.com",
    "联系13912345678,邮箱admin@fly63.com"
]

for text in texts:
    phone = phone_pattern.search(text)
    email = email_pattern.search(text)
    if phone:
        print("找到手机:", phone.group())
    if email:
        print("找到邮箱:", email.group())


常用正则表达式模式

基础模式

import re

text = "Python3.9 发布啦!价格是$199.99"

# 匹配数字
numbers = re.findall(r'\d+', text)
print("数字:", numbers)  # ['3', '9', '199', '99']

# 匹配单词
words = re.findall(r'[a-zA-Z]+', text)
print("单词:", words)  # ['Python', '发布啦', '价格是']

# 匹配价格
price = re.search(r'\$\d+\.\d{2}', text)
if price:
    print("价格:", price.group())  # $199.99

实用模式集合

import re

class PatternValidator:
    """常用正则表达式验证器"""
    
    @staticmethod
    def is_chinese(text):
        """检查是否为中文"""
        return bool(re.match(r'^[\u4e00-\u9fa5]+$', text))
    
    @staticmethod
    def is_id_card(id_card):
        """检查身份证格式(简单版本)"""
        return bool(re.match(r'^\d{17}[\dXx]$', id_card))
    
    @staticmethod
    def is_username(username):
        """检查用户名(4-16位字母数字下划线)"""
        return bool(re.match(r'^[a-zA-Z0-9_]{4,16}$', username))
    
    @staticmethod
    def extract_urls(text):
        """提取URL"""
        return re.findall(r'https?://[^\s]+', text)

# 使用示例
validator = PatternValidator()

print("中文验证:", validator.is_chinese("中文测试"))  # True
print("用户名验证:", validator.is_username("user_123"))  # True

text = "访问https://fly63.com和http://example.com"
print("提取URL:", validator.extract_urls(text))  # ['https://fly63.com', 'http://example.com']


文件内容处理

处理日志文件

import re
from collections import Counter

def analyze_log_file(file_path):
    """分析日志文件中的IP地址"""
    ip_counter = Counter()
    
    # IP地址模式
    ip_pattern = re.compile(r'\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b')
    
    try:
        with open(file_path, 'r', encoding='utf-8') as file:
            for line in file:
                ips = ip_pattern.findall(line)
                ip_counter.update(ips)
        
        print("访问统计:")
        for ip, count in ip_counter.most_common(10):
            print(f"  {ip}: {count}次")
            
    except FileNotFoundError:
        print("文件不存在")

# 使用示例
# analyze_log_file("access.log")

提取代码中的注释

import re

def extract_comments(code):
    """提取Python代码中的注释"""
    # 匹配单行注释
    single_line_comments = re.findall(r'#.*$', code, re.MULTILINE)
    
    # 匹配多行注释
    multi_line_comments = re.findall(r"'''.*?'''", code, re.DOTALL)
    multi_line_comments.extend(re.findall(r'""".*?"""', code, re.DOTALL))
    
    return single_line_comments, multi_line_comments

# 示例代码
sample_code = '''
def calculate_sum(a, b):
    # 这是一个加法函数
    """计算两个数的和"""
    return a + b  # 返回结果

# 主程序
if __name__ == "__main__":
    result = calculate_sum(5, 3)
'''

single, multi = extract_comments(sample_code)
print("单行注释:", single)
print("多行注释:", multi)


高级技巧

非贪婪匹配

import re

text = "<div>内容1</div><div>内容2</div>"

# 贪婪匹配(默认)
greedy = re.findall(r'<div>.*</div>', text)
print("贪婪匹配:", greedy)  # ['<div>内容1</div><div>内容2</div>']

# 非贪婪匹配
non_greedy = re.findall(r'<div>.*?</div>', text)
print("非贪婪匹配:", non_greedy)  # ['<div>内容1</div>', '<div>内容2</div>']

前后查找

import re

text = "苹果价格:¥20, 香蕉价格:¥15, 橙子价格:¥25"

# 查找价格数字(在¥之后)
prices = re.findall(r'¥(\d+)', text)
print("价格:", prices)  # ['20', '15', '25']

# 查找商品名(在价格之前)
products = re.findall(r'(\w+)(?=价格)', text)
print("商品:", products)  # ['苹果', '香蕉', '橙子']


常见问题解决

处理特殊字符

import re

def escape_special_chars(text):
    """转义正则表达式特殊字符"""
    special_chars = r'\.^$*+?{}[]|()'
    for char in special_chars:
        text = text.replace(char, '\\' + char)
    return text

# 搜索包含特殊字符的文本
search_text = "价格是$20.99 (特价)"
escaped_text = escape_special_chars(search_text)
pattern = re.compile(escaped_text)

text = "当前价格是$20.99 (特价),很划算"
match = pattern.search(text)
if match:
    print("找到:", match.group())  # 价格是$20.99 (特价)

性能优化

import re
import time

def measure_performance():
    """比较编译和未编译的性能"""
    text = "测试文本" * 1000
    
    # 未编译
    start = time.time()
    for i in range(1000):
        re.search(r'测试', text)
    uncompiled_time = time.time() - start
    
    # 编译后
    pattern = re.compile(r'测试')
    start = time.time()
    for i in range(1000):
        pattern.search(text)
    compiled_time = time.time() - start
    
    print(f"未编译: {uncompiled_time:.4f}秒")
    print(f"编译后: {compiled_time:.4f}秒")
    print(f"性能提升: {uncompiled_time/compiled_time:.1f}倍")

measure_performance()


调试技巧

测试正则表达式

import re

def test_regex(pattern, test_cases):
    """测试正则表达式"""
    compiled = re.compile(pattern)
    
    print(f"测试模式: {pattern}")
    print("-" * 40)
    
    for test_case in test_cases:
        match = compiled.search(test_case)
        result = "匹配" if match else "不匹配"
        print(f"'{test_case}' -> {result}")
        if match:
            print(f"  匹配内容: {match.group()}")

# 测试邮箱验证
email_pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
test_cases = [
    "test@fly63.com",
    "invalid-email",
    "user.name@domain.co.uk",
    "missing@dot"
]

test_regex(email_pattern, test_cases)

掌握正则表达式需要练习,建议从简单的模式开始,逐步尝试更复杂的匹配。在实际项目中,正则表达式能大大简化文本处理工作。


正则表达式修饰符 - 可选标志

正则表达式可以包含一些可选标志修饰符来控制匹配的模式。

以下标志可以单独使用,也可以通过按位或(|)组合使用。例如,re.IGNORECASE | re.MULTILINE 表示同时启用忽略大小写和多行模式。

修饰符描述实例
re.IGNORECASE 或 re.I使匹配对大小写不敏感
import re
pattern = re.compile(r'apple', flags=re.IGNORECASE)
result = pattern.match('Apple')
print(result.group())  # 输出: 'Apple'
re.MULTILINE 或 re.M多行匹配,影响 ^ 和 $,使它们匹配字符串的每一行的开头和结尾。
import re
pattern = re.compile(r'^\d+', flags=re.MULTILINE)
text = '123\n456\n789'
result = pattern.findall(text)
print(result)  # 输出: ['123', '456', '789']
re.DOTALL 或 re.S:使 . 匹配包括换行符在内的任意字符。
import re
pattern = re.compile(r'a.b', flags=re.DOTALL)
result = pattern.match('a\nb')
print(result.group())  # 输出: 'a\nb'
re.ASCII使 \w, \W, \b, \B, \d, \D, \s, \S 仅匹配 ASCII 字符。
import re
pattern = re.compile(r'\w+', flags=re.ASCII)
result = pattern.match('Hello123')
print(result.group())  # 输出: 'Hello123'
re.VERBOSE 或 re.X忽略空格和注释,可以更清晰地组织复杂的正则表达式。
import re
pattern = re.compile(r'''
    \d+  # 匹配数字
    [a-z]+  # 匹配小写字母
''', flags=re.VERBOSE)
result = pattern.match('123abc')
print(result.group())  # 输出: '123abc'


正则表达式模式

模式字符串使用特殊的语法来表示一个正则表达式。

字母和数字表示他们自身。一个正则表达式模式中的字母和数字匹配同样的字符串。

多数字母和数字前加一个反斜杠时会拥有不同的含义。

标点符号只有被转义时才匹配自身,否则它们表示特殊的含义。

反斜杠本身需要使用反斜杠转义。

由于正则表达式通常都包含反斜杠,所以你最好使用原始字符串来表示它们。模式元素(如 r'\t',等价于 \\t )匹配相应的特殊字符。

下表列出了正则表达式模式语法中的特殊元素。如果你使用模式的同时提供了可选的标志参数,某些模式元素的含义会改变。

模式描述
^匹配字符串的开头
$匹配字符串的末尾。
.匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符。
[...]用来匹配所包含的任意一个字符,例如 [amk] 匹配 'a','m'或'k'
[^...]不在[]中的字符:[^abc] 匹配除了a,b,c之外的字符。
re*匹配0个或多个的表达式。
re+匹配1个或多个的表达式。
re?匹配0个或1个由前面的正则表达式定义的片段,非贪婪方式
re{ n}匹配n个前面表达式。例如,"o{2}"不能匹配"Bob"中的"o",但是能匹配"food"中的两个o。
re{ n,}精确匹配n个前面表达式。例如,"o{2,}"不能匹配"Bob"中的"o",但能匹配"foooood"中的所有o。"o{1,}"等价于"o+"。"o{0,}"则等价于"o*"。
re{ n, m}匹配 n 到 m 次由前面的正则表达式定义的片段,贪婪方式
a| b匹配a或b
(re)匹配括号内的表达式,也表示一个组
(?imx)正则表达式包含三种可选标志:i, m, 或 x 。只影响括号中的区域。
(?-imx)正则表达式关闭 i, m, 或 x 可选标志。只影响括号中的区域。
(?: re)类似 (...), 但是不表示一个组
(?imx: re)在括号中使用i, m, 或 x 可选标志
(?-imx: re)在括号中不使用i, m, 或 x 可选标志
(?#...)注释.
(?= re)前向肯定界定符。如果所含正则表达式,以 ... 表示,在当前位置成功匹配时成功,否则失败。但一旦所含表达式已经尝试,匹配引擎根本没有提高;模式的剩余部分还要尝试界定符的右边。
(?! re)前向否定界定符。与肯定界定符相反;当所含表达式不能在字符串当前位置匹配时成功。
(?> re)匹配的独立模式,省去回溯。
\w匹配数字字母下划线
\W匹配非数字字母下划线
\s匹配任意空白字符,等价于 [\t\n\r\f]。
\S匹配任意非空字符
\d匹配任意数字,等价于 [0-9]。
\D匹配任意非数字
\A匹配字符串开始
\Z匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串。
\z匹配字符串结束
\G匹配最后匹配完成的位置。
\b匹配一个单词边界,也就是指单词和空格间的位置。例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。
\B匹配非单词边界。'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。
\n, \t, 等。匹配一个换行符。匹配一个制表符, 等
\1...\9匹配第n个分组的内容。
\10匹配第n个分组的内容,如果它经匹配。否则指的是八进制字符码的表达式。

正则表达式实例

字符匹配

实例描述
python匹配 "python".

字符类

实例描述
[Pp]ython匹配 "Python" 或 "python"
rub[ye]匹配 "ruby" 或 "rube"
[aeiou]匹配中括号内的任意一个字母
[0-9]匹配任何数字。类似于 [0123456789]
[a-z]匹配任何小写字母
[A-Z]匹配任何大写字母
[a-zA-Z0-9]匹配任何字母及数字
[^aeiou]除了aeiou字母以外的所有字符
[^0-9]匹配除了数字外的字符

特殊字符类

实例描述
.匹配除 "\n" 之外的任何单个字符。要匹配包括 '\n' 在内的任何字符,请使用象 '[.\n]' 的模式。
\d匹配一个数字字符。等价于 [0-9]。
\D匹配一个非数字字符。等价于 [^0-9]。
\s匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。
\S匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。
\w匹配包括下划线的任何单词字符。等价于'[A-Za-z0-9_]'。
\W匹配任何非单词字符。等价于 '[^A-Za-z0-9_]'。

本文内容仅供个人学习/研究/参考使用,不构成任何决策建议或专业指导。分享/转载时请标明原文来源,同时请勿将内容用于商业售卖、虚假宣传等非学习用途哦~感谢您的理解与支持!

链接: https://fly63.com/course/36_2109

目录选择