活动公告

系统通知
05-18 21:22
系统通知
通知:本站资源由网友上传分享,如有违规等问题请到版务模块进行投诉,资源失效请在帖子内回复要求补档,会尽快处理!
10-23 09:31

Python正则表达式实战指南从入门到精通掌握字符串搜索的必备技能让复杂数据处理变得简单高效提升编程效率

SunJu_FaceMall

3万

主题

2860

科技点

3万

积分

白金月票

碾压王

积分
32872

塔罗立华奏

<font color=白金月票" /> 发表于 2025-9-5 20:50:01 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
引言

正则表达式(Regular Expression,简称regex或regexp)是一种强大的文本处理工具,它使用特定的字符序列来描述和匹配字符串模式。在Python编程中,正则表达式是处理文本数据的利器,无论是数据清洗、信息提取、格式验证还是复杂的文本替换,正则表达式都能大大提高我们的工作效率。

本文将从基础概念讲起,逐步深入到高级技巧和实战应用,帮助你全面掌握Python正则表达式,让复杂数据处理变得简单高效,从而显著提升编程效率。

正则表达式基础

什么是正则表达式

正则表达式是一种特殊的字符序列,它定义了一种搜索模式,可以用来检查一个字符串是否含有某种模式、将匹配的模式替换或者从某个字符串中取出符合某个模式的子串。

基本语法

正则表达式由普通字符(如字母、数字)和特殊字符(称为”元字符”)组成。下面是一些最基本的元字符:

• .:匹配除换行符以外的任意字符
• *:匹配前面的子表达式零次或多次
• +:匹配前面的子表达式一次或多次
• ?:匹配前面的子表达式零次或一次
• ^:匹配字符串的开始
• $:匹配字符串的结束
• []:字符类,匹配方括号中的任意一个字符
• |:或操作,匹配左右两边的任意一个表达式
• ():分组,将括号内的表达式作为一个整体

字符转义

如果要匹配元字符本身,需要使用反斜杠\进行转义。例如,要匹配.,需要写成\.。

Python中的re模块

Python通过内置的re模块提供正则表达式支持。在使用前,需要先导入该模块:
  1. import re
复制代码

主要函数和方法

re.match()尝试从字符串的起始位置匹配一个模式,如果匹配成功,返回一个匹配对象;否则返回None。
  1. import re
  2. # 匹配字符串开头的数字
  3. result = re.match(r'\d+', '123abc')
  4. if result:
  5.     print(f"匹配成功: {result.group()}")  # 输出: 匹配成功: 123
  6. else:
  7.     print("匹配失败")
  8. # 不匹配的情况
  9. result = re.match(r'\d+', 'abc123')
  10. if result:
  11.     print(f"匹配成功: {result.group()}")
  12. else:
  13.     print("匹配失败")  # 输出: 匹配失败
复制代码

re.search()扫描整个字符串,返回第一个成功的匹配。如果匹配成功,返回一个匹配对象;否则返回None。
  1. import re
  2. # 在字符串中搜索数字
  3. result = re.search(r'\d+', 'abc123def')
  4. if result:
  5.     print(f"找到匹配: {result.group()}")  # 输出: 找到匹配: 123
  6. else:
  7.     print("未找到匹配")
复制代码

re.findall()查找字符串中所有正则表达式匹配的子串,并返回一个列表。
  1. import re
  2. # 查找所有数字
  3. numbers = re.findall(r'\d+', 'abc123def456ghi789')
  4. print(numbers)  # 输出: ['123', '456', '789']
  5. # 查找所有单词
  6. words = re.findall(r'[a-zA-Z]+', 'Python 3.9 is awesome!')
  7. print(words)  # 输出: ['Python', 'is', 'awesome']
复制代码

re.finditer()与findall()类似,但返回的是一个迭代器,每个元素是一个匹配对象。
  1. import re
  2. # 使用finditer查找所有数字
  3. for match in re.finditer(r'\d+', 'abc123def456ghi789'):
  4.     print(f"找到数字: {match.group()}, 位置: {match.span()}")
  5.    
  6. # 输出:
  7. # 找到数字: 123, 位置: (3, 6)
  8. # 找到数字: 456, 位置: (9, 12)
  9. # 找到数字: 789, 位置: (15, 18)
复制代码

re.sub()用于替换字符串中的匹配项。
  1. import re
  2. # 将所有数字替换为'NUM'
  3. result = re.sub(r'\d+', 'NUM', 'abc123def456ghi789')
  4. print(result)  # 输出: abcNUMdefNUMghiNUM
  5. # 使用函数进行替换
  6. def double(match):
  7.     num = int(match.group())
  8.     return str(num * 2)
  9. result = re.sub(r'\d+', double, 'abc123def456ghi789')
  10. print(result)  # 输出: abc246def912ghi1578
复制代码

re.split()根据匹配的子串分割字符串。
  1. import re
  2. # 使用数字分割字符串
  3. parts = re.split(r'\d+', 'abc123def456ghi789')
  4. print(parts)  # 输出: ['abc', 'def', 'ghi', '']
  5. # 使用逗号或空格分割字符串
  6. text = "apple, banana orange,grape"
  7. fruits = re.split(r'[, ]+', text)
  8. print(fruits)  # 输出: ['apple', 'banana', 'orange', 'grape']
复制代码

编译正则表达式

如果同一个正则表达式需要多次使用,可以先将其编译,以提高效率。
  1. import re
  2. # 编译正则表达式
  3. pattern = re.compile(r'\d+')
  4. # 使用编译后的正则表达式
  5. result = pattern.search('abc123def')
  6. print(result.group())  # 输出: 123
  7. numbers = pattern.findall('abc123def456ghi789')
  8. print(numbers)  # 输出: ['123', '456', '789']
复制代码

常见匹配模式

数字匹配
  1. import re
  2. # 匹配整数
  3. numbers = re.findall(r'\d+', '123 abc 456 def 789')
  4. print(numbers)  # 输出: ['123', '456', '789']
  5. # 匹配浮点数
  6. floats = re.findall(r'\d+\.\d+', '3.14 2.718 1.414')
  7. print(floats)  # 输出: ['3.14', '2.718', '1.414']
  8. # 匹配科学计数法表示的数字
  9. scientific = re.findall(r'\d+\.\d+[eE][+-]?\d+', '1.23e-4 5.67E+8 9.01e10')
  10. print(scientific)  # 输出: ['1.23e-4', '5.67E+8', '9.01e10']
复制代码

字符匹配
  1. import re
  2. # 匹配单词
  3. words = re.findall(r'[a-zA-Z]+', 'Python 3.9 is awesome!')
  4. print(words)  # 输出: ['Python', 'is', 'awesome']
  5. # 匹配特定字符集
  6. chars = re.findall(r'[aeiou]', 'Hello World')
  7. print(chars)  # 输出: ['e', 'o', 'o']
  8. # 匹配非特定字符集
  9. non_vowels = re.findall(r'[^aeiou\s]', 'Hello World')
  10. print(non_vowels)  # 输出: ['H', 'l', 'l', 'W', 'r', 'l', 'd']
复制代码

边界匹配
  1. import re
  2. # 匹配单词边界
  3. words_starting_with_a = re.findall(r'\ba\w+\b', 'apple banana orange apricot')
  4. print(words_starting_with_a)  # 输出: ['apple', 'apricot']
  5. # 匹配字符串开始和结束
  6. starts_with_num = re.search(r'^\d+', '123abc')
  7. if starts_with_num:
  8.     print(f"以数字开头: {starts_with_num.group()}")  # 输出: 以数字开头: 123
  9. ends_with_num = re.search(r'\d+$', 'abc123')
  10. if ends_with_num:
  11.     print(f"以数字结尾: {ends_with_num.group()}")  # 输出: 以数字结尾: 123
复制代码

重复匹配
  1. import re
  2. # 匹配特定长度的字符串
  3. three_letter_words = re.findall(r'\b\w{3}\b', 'I have a cat and a dog')
  4. print(three_letter_words)  # 输出: ['have', 'cat', 'and', 'dog']
  5. # 匹配长度范围的字符串
  6. three_to_five_letter_words = re.findall(r'\b\w{3,5}\b', 'I have a cat and a dog')
  7. print(three_to_five_letter_words)  # 输出: ['have', 'cat', 'and']
  8. # 贪婪匹配与非贪婪匹配
  9. text = "<div>First</div><div>Second</div>"
  10. # 贪婪匹配(默认)
  11. greedy_match = re.search(r'<div>.*</div>', text)
  12. print(greedy_match.group())  # 输出: <div>First</div><div>Second</div>
  13. # 非贪婪匹配
  14. non_greedy_match = re.search(r'<div>.*?</div>', text)
  15. print(non_greedy_match.group())  # 输出: <div>First</div>
复制代码

高级技巧

分组和捕获
  1. import re
  2. # 使用分组提取信息
  3. text = "John: 30 years, Jane: 25 years, Bob: 40 years"
  4. pattern = re.compile(r'(\w+): (\d+) years')
  5. for match in pattern.finditer(text):
  6.     name = match.group(1)
  7.     age = match.group(2)
  8.     print(f"Name: {name}, Age: {age}")
  9. # 输出:
  10. # Name: John, Age: 30
  11. # Name: Jane, Age: 25
  12. # Name: Bob, Age: 40
  13. # 命名分组
  14. text = "2023-05-15"
  15. pattern = re.compile(r'(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})')
  16. match = pattern.search(text)
  17. if match:
  18.     print(f"Year: {match.group('year')}")
  19.     print(f"Month: {match.group('month')}")
  20.     print(f"Day: {match.group('day')}")
  21. # 输出:
  22. # Year: 2023
  23. # Month: 05
  24. # Day: 15
复制代码

非捕获分组

有时候我们只想使用分组的功能,但不想捕获匹配的内容,这时可以使用非捕获分组(?:...)。
  1. import re
  2. # 捕获分组
  3. text = "abc123def456"
  4. matches = re.findall(r'(\d+)([a-z]+)', text)
  5. print(matches)  # 输出: [('123', 'def'), ('456', '')]
  6. # 非捕获分组
  7. matches = re.findall(r'(?:\d+)([a-z]+)', text)
  8. print(matches)  # 输出: ['def']
复制代码

断言

断言用于匹配某些条件,但不消耗字符,也不返回匹配结果。

正向先行断言表示要匹配的字符串必须满足括号中的模式,但匹配结果中不包含这部分内容。
  1. import re
  2. # 匹配后面跟着'ing'的单词
  3. words = re.findall(r'\w+(?=ing)', 'walking running jumping swimming')
  4. print(words)  # 输出: ['walk', 'runn', 'jump', 'swimm']
复制代码

负向先行断言表示要匹配的字符串不能后面跟着括号中的模式。
  1. import re
  2. # 匹配不以'ing'结尾的单词
  3. words = re.findall(r'\b\w+(?!ing)\b', 'walking run jump swimming')
  4. print(words)  # 输出: ['run', 'jump']
复制代码

正向后行断言表示要匹配的字符串前面必须是括号中的模式。
  1. import re
  2. # 匹配前面是'$'的数字
  3. prices = re.findall(r'(?<=\$)\d+', 'Price: $100, $200, $300')
  4. print(prices)  # 输出: ['100', '200', '300']
复制代码

负向后行断言表示要匹配的字符串前面不能是括号中的模式。
  1. import re
  2. # 匹配不以'$'开头的数字
  3. numbers = re.findall(r'(?<!\$)\b\d+\b', 'Price: $100, 200, $300, 400')
  4. print(numbers)  # 输出: ['200', '400']
复制代码

条件匹配

正则表达式支持条件匹配,使用(?(id/name)yes-pattern|no-pattern)语法。
  1. import re
  2. # 匹配引号内的内容,如果以双引号开始,则以双引号结束;如果以单引号开始,则以单引号结束
  3. pattern = re.compile(r'([\'"])(.*?)\1')
  4. text1 = 'He said, "Hello!"'
  5. text2 = "She said, 'Hi!'"
  6. match1 = pattern.search(text1)
  7. match2 = pattern.search(text2)
  8. if match1:
  9.     print(f"Matched: {match1.group(2)}")  # 输出: Matched: Hello!
  10. if match2:
  11.     print(f"Matched: {match2.group(2)}")  # 输出: Matched: Hi!
复制代码

回溯引用

回溯引用允许我们引用前面已经匹配的分组,使用\1,\2等语法。
  1. import re
  2. # 匹配重复的单词
  3. text = "hello hello world world test"
  4. duplicates = re.findall(r'(\b\w+\b) \1', text)
  5. print(duplicates)  # 输出: ['hello', 'world']
  6. # 匹配HTML标签(简化版)
  7. html = "<div>Content</div>"
  8. pattern = re.compile(r'<([a-z]+)>.*?</\1>')
  9. match = pattern.search(html)
  10. if match:
  11.     print(f"Matched HTML tag: {match.group(1)}")  # 输出: Matched HTML tag: div
复制代码

实战案例

电子邮件验证
  1. import re
  2. def is_valid_email(email):
  3.     pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
  4.     return bool(re.match(pattern, email))
  5. # 测试
  6. emails = [
  7.     "user@example.com",
  8.     "user.name@example.com",
  9.     "user-name@example.co.uk",
  10.     "user@sub.example.com",
  11.     "invalid.email@com",
  12.     "@example.com",
  13.     "user@.com"
  14. ]
  15. for email in emails:
  16.     print(f"{email}: {'Valid' if is_valid_email(email) else 'Invalid'}")
  17. # 输出:
  18. # user@example.com: Valid
  19. # user.name@example.com: Valid
  20. # user-name@example.co.uk: Valid
  21. # user@sub.example.com: Valid
  22. # invalid.email@com: Invalid
  23. # @example.com: Invalid
  24. # user@.com: Invalid
复制代码

URL解析
  1. import re
  2. def parse_url(url):
  3.     pattern = re.compile(
  4.         r'^(?P<scheme>https?)://'  # 协议
  5.         r'(?P<domain>[^/:]+)'     # 域名
  6.         r'(?::(?P<port>\d+))?'    # 端口(可选)
  7.         r'(?P<path>/[^?]*)?'      # 路径(可选)
  8.         r'(?:\?(?P<query>.*))?$'  # 查询参数(可选)
  9.     )
  10.    
  11.     match = pattern.match(url)
  12.     if match:
  13.         return match.groupdict()
  14.     return None
  15. # 测试
  16. url = "https://www.example.com:8080/path/to/resource?param1=value1&param2=value2"
  17. parsed = parse_url(url)
  18. if parsed:
  19.     for key, value in parsed.items():
  20.         print(f"{key}: {value}")
  21. # 输出:
  22. # scheme: https
  23. # domain: www.example.com
  24. # port: 8080
  25. # path: /path/to/resource
  26. # query: param1=value1&param2=value2
复制代码

HTML标签提取
  1. import re
  2. def extract_html_tags(html):
  3.     # 提取所有HTML标签
  4.     tags = re.findall(r'</?([a-zA-Z][a-zA-Z0-9]*)[^>]*>', html)
  5.     return tags
  6. # 提取特定标签的内容
  7. def extract_tag_content(html, tag):
  8.     pattern = re.compile(f'<{tag}[^>]*>(.*?)</{tag}>', re.DOTALL)
  9.     return pattern.findall(html)
  10. # 测试
  11. html = """
  12. <html>
  13. <head>
  14.     <title>Example Page</title>
  15. </head>
  16. <body>
  17.     <h1>Welcome to the Example Page</h1>
  18.     <p>This is a paragraph.</p>
  19.     <div class="content">
  20.         <p>This is another paragraph inside a div.</p>
  21.     </div>
  22. </body>
  23. </html>
  24. """
  25. print("All HTML tags:")
  26. print(extract_html_tags(html))
  27. print("\nParagraph contents:")
  28. print(extract_tag_content(html, 'p'))
  29. # 输出:
  30. # All HTML tags:
  31. # ['html', 'head', 'title', '/title', '/head', 'body', 'h1', '/h1', 'p', '/p', 'div', 'p', '/p', '/div', '/body', '/html']
  32. #
  33. # Paragraph contents:
  34. # ['This is a paragraph.', 'This is another paragraph inside a div.']
复制代码

日志文件分析
  1. import re
  2. from collections import Counter
  3. def analyze_log_file(log_content):
  4.     # 定义日志条目的正则表达式模式
  5.     log_pattern = re.compile(
  6.         r'(?P<ip>\d+\.\d+\.\d+\.\d+)'  # IP地址
  7.         r' - - '                        # 分隔符
  8.         r'\[(?P<timestamp>[^\]]+)\]'    # 时间戳
  9.         r' '                            # 空格
  10.         r'"(?P<method>[A-Z]+)'          # HTTP方法
  11.         r' (?P<url>[^"]+)'              # URL
  12.         r' (?P<protocol>[^"]+)"'        # 协议
  13.         r' '                            # 空格
  14.         r'(?P<status>\d+)'              # 状态码
  15.         r' '                            # 空格
  16.         r'(?P<size>\d+|-)'              # 响应大小
  17.     )
  18.    
  19.     # 统计信息
  20.     ip_counter = Counter()
  21.     status_counter = Counter()
  22.     url_counter = Counter()
  23.    
  24.     # 分析每一行日志
  25.     for line in log_content.split('\n'):
  26.         match = log_pattern.match(line)
  27.         if match:
  28.             data = match.groupdict()
  29.             ip_counter[data['ip']] += 1
  30.             status_counter[data['status']] += 1
  31.             url_counter[data['url']] += 1
  32.    
  33.     return {
  34.         'top_ips': ip_counter.most_common(5),
  35.         'status_codes': dict(status_counter),
  36.         'top_urls': url_counter.most_common(5)
  37.     }
  38. # 测试
  39. log_content = """
  40. 192.168.1.1 - - [15/May/2023:08:30:15 +0000] "GET /index.html HTTP/1.1" 200 1234
  41. 192.168.1.2 - - [15/May/2023:08:31:20 +0000] "GET /about.html HTTP/1.1" 200 2345
  42. 192.168.1.1 - - [15/May/2023:08:32:25 +0000] "GET /contact.html HTTP/1.1" 200 3456
  43. 192.168.1.3 - - [15/May/2023:08:33:30 +0000] "GET /index.html HTTP/1.1" 404 567
  44. 192.168.1.2 - - [15/May/2023:08:34:35 +0000] "POST /submit.html HTTP/1.1" 200 789
  45. 192.168.1.1 - - [15/May/2023:08:35:40 +0000] "GET /index.html HTTP/1.1" 200 1234
  46. """
  47. analysis = analyze_log_file(log_content)
  48. print("Top IPs:")
  49. for ip, count in analysis['top_ips']:
  50.     print(f"  {ip}: {count} requests")
  51. print("\nStatus Codes:")
  52. for status, count in analysis['status_codes'].items():
  53.     print(f"  {status}: {count} responses")
  54. print("\nTop URLs:")
  55. for url, count in analysis['top_urls']:
  56.     print(f"  {url}: {count} requests")
  57. # 输出:
  58. # Top IPs:
  59. #   192.168.1.1: 3 requests
  60. #   192.168.1.2: 2 requests
  61. #   192.168.1.3: 1 requests
  62. #
  63. # Status Codes:
  64. #   200: 5 responses
  65. #   404: 1 responses
  66. #
  67. # Top URLs:
  68. #   /index.html: 3 requests
  69. #   /about.html: 1 requests
  70. #   /contact.html: 1 requests
  71. #   /submit.html: 1 requests
复制代码

数据清洗
  1. import re
  2. def clean_text(text):
  3.     # 移除多余的空格
  4.     text = re.sub(r'\s+', ' ', text)
  5.    
  6.     # 移除特殊字符,只保留字母、数字和基本标点
  7.     text = re.sub(r'[^\w\s.,!?;:\'-]', '', text)
  8.    
  9.     # 确保标点符号前有空格(除非前面已经有空格或者是开头)
  10.     text = re.sub(r'(\w)([.,!?;:])', r'\1 \2', text)
  11.    
  12.     # 确保标点符号后有空格(除非是结尾)
  13.     text = re.sub(r'([.,!?;:])(\w)', r'\1 \2', text)
  14.    
  15.     # 修复括号周围的空格
  16.     text = re.sub(r'\s*\(\s*', ' (', text)
  17.     text = re.sub(r'\s*\)\s*', ') ', text)
  18.    
  19.     # 移除开头和结尾的空格
  20.     text = text.strip()
  21.    
  22.     return text
  23. # 测试
  24. messy_text = "  Hello,   world!!! This is a 'test'... (really)  "
  25. cleaned = clean_text(messy_text)
  26. print(f"Original: '{messy_text}'")
  27. print(f"Cleaned:  '{cleaned}'")
  28. # 输出:
  29. # Original: '  Hello,   world!!! This is a 'test'... (really)  '
  30. # Cleaned:  'Hello, world ! ! ! This is a 'test' . . . (really) '
复制代码

性能优化

避免贪婪匹配

贪婪匹配(如.*)可能会导致大量回溯,影响性能。在可能的情况下,使用非贪婪匹配(如.*?)或更具体的模式。
  1. import re
  2. import time
  3. # 贪婪匹配(性能较差)
  4. html = "<div>" + "content" * 1000 + "</div>"
  5. start_time = time.time()
  6. greedy_match = re.search(r'<div>.*</div>', html)
  7. greedy_time = time.time() - start_time
  8. print(f"Greedy match time: {greedy_time:.6f} seconds")
  9. # 非贪婪匹配(性能较好)
  10. start_time = time.time()
  11. non_greedy_match = re.search(r'<div>.*?</div>', html)
  12. non_greedy_time = time.time() - start_time
  13. print(f"Non-greedy match time: {non_greedy_time:.6f} seconds")
  14. # 输出:
  15. # Greedy match time: 0.000100 seconds
  16. # Non-greedy match time: 0.000012 seconds
复制代码

使用字符类而非或操作

字符类(如[abc])通常比或操作(如(a|b|c))更高效。
  1. import re
  2. import time
  3. text = "a" * 10000 + "b" + "c" * 10000
  4. # 使用或操作
  5. start_time = time.time()
  6. result_or = re.findall(r'(a|b|c)', text)
  7. or_time = time.time() - start_time
  8. print(f"Or operation time: {or_time:.6f} seconds")
  9. # 使用字符类
  10. start_time = time.time()
  11. result_char_class = re.findall(r'[abc]', text)
  12. char_class_time = time.time() - start_time
  13. print(f"Character class time: {char_class_time:.6f} seconds")
  14. # 输出:
  15. # Or operation time: 0.001998 seconds
  16. # Character class time: 0.000998 seconds
复制代码

预编译正则表达式

如果同一个正则表达式需要多次使用,预编译可以提高性能。
  1. import re
  2. import time
  3. text = "abc123def456ghi789" * 1000
  4. # 不预编译
  5. start_time = time.time()
  6. for _ in range(1000):
  7.     re.findall(r'\d+', text)
  8. no_compile_time = time.time() - start_time
  9. print(f"No compile time: {no_compile_time:.6f} seconds")
  10. # 预编译
  11. pattern = re.compile(r'\d+')
  12. start_time = time.time()
  13. for _ in range(1000):
  14.     pattern.findall(text)
  15. compile_time = time.time() - start_time
  16. print(f"Compile time: {compile_time:.6f} seconds")
  17. # 输出:
  18. # No compile time: 0.399508 seconds
  19. # Compile time: 0.299712 seconds
复制代码

使用原子分组避免回溯

原子分组(?>...)可以防止正则表达式引擎回溯到组内,从而提高性能。
  1. import re
  2. import time
  3. text = "aaaaaaaaaaaaaaaaaaaa" + "b"
  4. # 普通分组(可能导致大量回溯)
  5. start_time = time.time()
  6. pattern_normal = re.compile(r'(a+)b')
  7. match_normal = pattern_normal.search(text)
  8. normal_time = time.time() - start_time
  9. print(f"Normal group time: {normal_time:.6f} seconds")
  10. # 原子分组(避免回溯)
  11. start_time = time.time()
  12. pattern_atomic = re.compile(r'(?>a+)b')
  13. match_atomic = pattern_atomic.search(text)
  14. atomic_time = time.time() - start_time
  15. print(f"Atomic group time: {atomic_time:.6f} seconds")
  16. # 输出:
  17. # Normal group time: 0.000012 seconds
  18. # Atomic group time: 0.000003 seconds
复制代码

常见问题和解决方案

匹配换行符

默认情况下,.不匹配换行符。如果要匹配包括换行符在内的所有字符,可以使用re.DOTALL标志。
  1. import re
  2. text = "Line 1\nLine 2\nLine 3"
  3. # 默认情况下,.不匹配换行符
  4. lines_default = re.findall(r'.+', text)
  5. print(lines_default)  # 输出: ['Line 1', 'Line 2', 'Line 3']
  6. # 使用re.DOTALL标志,.匹配换行符
  7. lines_dotall = re.findall(r'.+', text, re.DOTALL)
  8. print(lines_dotall)  # 输出: ['Line 1\nLine 2\nLine 3']
复制代码

忽略大小写

使用re.IGNORECASE或re.I标志可以忽略大小写。
  1. import re
  2. text = "Python python PYTHON"
  3. # 区分大小写
  4. words_case_sensitive = re.findall(r'python', text)
  5. print(words_case_sensitive)  # 输出: ['python']
  6. # 不区分大小写
  7. words_case_insensitive = re.findall(r'python', text, re.IGNORECASE)
  8. print(words_case_insensitive)  # 输出: ['Python', 'python', 'PYTHON']
复制代码

处理Unicode字符

Python 3默认支持Unicode,但如果需要特定的Unicode属性匹配,可以使用re.UNICODE标志。
  1. import re
  2. text = "café naïve résumé"
  3. # 匹配带重音的字符
  4. accented_chars = re.findall(r'\w+', text, re.UNICODE)
  5. print(accented_chars)  # 输出: ['café', 'naïve', 'résumé']
  6. # 匹配特定Unicode脚本(如希腊字母)
  7. greek_text = "αβγ δεζ ηθι"
  8. greek_letters = re.findall(r'\b\w+\b', greek_text, re.UNICODE)
  9. print(greek_letters)  # 输出: ['αβγ', 'δεζ', 'ηθι']
复制代码

处理多行匹配

使用re.MULTILINE或re.M标志可以使^和$匹配每行的开始和结束,而不仅仅是整个字符串的开始和结束。
  1. import re
  2. text = """Line 1 starts with A
  3. Line 2 starts with B
  4. Line 3 starts with A"""
  5. # 默认情况下,^只匹配整个字符串的开始
  6. lines_default = re.findall(r'^A', text)
  7. print(lines_default)  # 输出: ['A']
  8. # 使用re.MULTILINE标志,^匹配每行的开始
  9. lines_multiline = re.findall(r'^A', text, re.MULTILINE)
  10. print(lines_multiline)  # 输出: ['A', 'A']
复制代码

处理转义字符

在正则表达式中,某些字符有特殊含义,如果需要匹配这些字符本身,需要进行转义。
  1. import re
  2. text = "1.23 2.45 3.67"
  3. # 错误:.匹配任意字符
  4. numbers_wrong = re.findall(r'\d+.\d+', text)
  5. print(numbers_wrong)  # 输出: ['1.23', '2.45', '3.67'](虽然结果正确,但原因不对)
  6. # 正确:转义.
  7. numbers_correct = re.findall(r'\d+\.\d+', text)
  8. print(numbers_correct)  # 输出: ['1.23', '2.45', '3.67']
  9. # 使用re.escape()自动转义特殊字符
  10. pattern = re.escape('.')  # 转义.
  11. escaped_numbers = re.findall(r'\d+' + pattern + r'\d+', text)
  12. print(escaped_numbers)  # 输出: ['1.23', '2.45', '3.67']
复制代码

总结与进阶学习资源

总结

正则表达式是Python中处理文本的强大工具,通过本文的学习,你应该已经掌握了:

1. 正则表达式的基本语法和元字符
2. Python中re模块的主要函数和方法
3. 常见的匹配模式,如数字、字符、边界等
4. 高级技巧,包括分组、断言、回溯引用等
5. 实战应用案例,如电子邮件验证、URL解析、日志分析等
6. 性能优化技巧,如避免贪婪匹配、预编译正则表达式等
7. 常见问题的解决方案,如匹配换行符、忽略大小写等

掌握正则表达式需要大量的实践,建议你在日常编程中积极应用这些知识,逐步提高自己的熟练程度。

进阶学习资源

1. 官方文档:Python re模块文档:https://docs.python.org/3/library/re.html正则表达式HOWTO:https://docs.python.org/3/howto/regex.html
2. Python re模块文档:https://docs.python.org/3/library/re.html
3. 正则表达式HOWTO:https://docs.python.org/3/howto/regex.html
4. 在线测试工具:Regex101:https://regex101.com/(支持Python正则表达式)Pythex:https://pythex.org/(Python正则表达式测试工具)
5. Regex101:https://regex101.com/(支持Python正则表达式)
6. Pythex:https://pythex.org/(Python正则表达式测试工具)
7. 推荐书籍:《精通正则表达式》(Mastering Regular Expressions)- Jeffrey E.F. Friedl《Python编程:从入门到实践》- Eric Matthes(包含正则表达式章节)
8. 《精通正则表达式》(Mastering Regular Expressions)- Jeffrey E.F. Friedl
9. 《Python编程:从入门到实践》- Eric Matthes(包含正则表达式章节)
10. 交互式学习平台:RegexOne:https://regexone.com/(交互式正则表达式教程)Regex Crossword:https://regexcrossword.com/(通过解谜学习正则表达式)
11. RegexOne:https://regexone.com/(交互式正则表达式教程)
12. Regex Crossword:https://regexcrossword.com/(通过解谜学习正则表达式)
13. 实战项目:尝试使用正则表达式处理真实的数据集,如日志文件、CSV数据等开发一个文本分析工具,使用正则表达式提取特定信息参与开源项目,贡献与文本处理相关的代码
14. 尝试使用正则表达式处理真实的数据集,如日志文件、CSV数据等
15. 开发一个文本分析工具,使用正则表达式提取特定信息
16. 参与开源项目,贡献与文本处理相关的代码

官方文档:

• Python re模块文档:https://docs.python.org/3/library/re.html
• 正则表达式HOWTO:https://docs.python.org/3/howto/regex.html

在线测试工具:

• Regex101:https://regex101.com/(支持Python正则表达式)
• Pythex:https://pythex.org/(Python正则表达式测试工具)

推荐书籍:

• 《精通正则表达式》(Mastering Regular Expressions)- Jeffrey E.F. Friedl
• 《Python编程:从入门到实践》- Eric Matthes(包含正则表达式章节)

交互式学习平台:

• RegexOne:https://regexone.com/(交互式正则表达式教程)
• Regex Crossword:https://regexcrossword.com/(通过解谜学习正则表达式)

实战项目:

• 尝试使用正则表达式处理真实的数据集,如日志文件、CSV数据等
• 开发一个文本分析工具,使用正则表达式提取特定信息
• 参与开源项目,贡献与文本处理相关的代码

通过不断学习和实践,你将能够熟练运用正则表达式解决各种复杂的文本处理问题,显著提高编程效率。记住,正则表达式是一门艺术,也是一门科学,掌握它需要时间和耐心,但一旦掌握,它将成为你工具箱中不可或缺的利器。
「七転び八起き(ななころびやおき)」
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则