引言

正则表达式(Regular Expression,简称 Regex)是处理文本数据的一把利器,广泛应用于编程、数据分析、文本编辑等领域。通过使用正则表达式,我们可以高效地搜索、匹配、替换和验证文本。本文将深入探讨正则表达式的核心概念、常用语法、高级技巧,并结合实际案例,帮助您掌握正则表达式,实现完美匹配。

正则表达式基础

什么是正则表达式?

正则表达式是一种用于描述字符串模式的语言,它可以用来匹配、查找、替换或验证字符串。正则表达式由字符、符号和规则组成,可以构建出不同的字符匹配逻辑。

正则表达式的组成

  1. 字符:包括字母、数字、符号等。
  2. 元字符:具有特殊含义的符号,如 .*+?[]^$ 等。
  3. 量词:用于指定匹配的次数,如 *(零次或多次)、+(一次或多次)、?(零次或一次)等。
  4. 分组:将多个字符组合成一个整体进行匹配,如 ()[] 等。

正则表达式的执行过程

  1. 从左到右扫描字符串。
  2. 尝试从当前位置匹配正则表达式。
  3. 如果匹配成功,记录当前位置和匹配结果。
  4. 继续向右扫描,重复步骤 2 和 3。
  5. 匹配结束后,返回所有匹配结果。

常用正则表达式元字符

点号(.)

点号(.)匹配除换行符以外的任意单个字符。

import re

pattern = r'.*world.*'
text = 'hello world!'

match = re.match(pattern, text)
if match:
    print('匹配成功:', match.group())
else:
    print('匹配失败')

星号(*)

星号(*)匹配前面的子表达式零次或多次。

pattern = r'\b\w+\b'
text = 'This is a test string with multiple words.'

matches = re.findall(pattern, text)
print('匹配结果:', matches)

加号(+)

加号(+)匹配前面的子表达式一次或多次。

pattern = r'\d+'
text = 'There are 42 fruits in the basket.'

matches = re.findall(pattern, text)
print('匹配结果:', matches)

问号(?)

问号(?)匹配前面的子表达式零次或一次。

pattern = r'\b\w?\b'
text = 'This is a single word and this is a single-letter word.'

matches = re.findall(pattern, text)
print('匹配结果:', matches)

花括号({})

花括号({})用于指定匹配的次数。

pattern = r'\b\w{3}\b'
text = 'This is a three-letter word and this is a four-letter word.'

matches = re.findall(pattern, text)
print('匹配结果:', matches)

方括号([])

方括号([])用于匹配括号内的任意一个字符。

pattern = r'\b[a-z]+\b'
text = 'This is a string with various lowercase letters.'

matches = re.findall(pattern, text)
print('匹配结果:', matches)

脱字符(^)

脱字符(^)匹配字符串的开头。

pattern = r'^hello'
text = 'hello world!'

match = re.match(pattern, text)
if match:
    print('匹配成功:', match.group())
else:
    print('匹配失败')

美元符号($)

美元符号($)匹配字符串的结尾。

pattern = r'world$'
text = 'hello world!'

match = re.match(pattern, text)
if match:
    print('匹配成功:', match.group())
else:
    print('匹配失败')

高级正则表达式技巧

捕获组

捕获组用于捕获正则表达式中的匹配结果。

pattern = r'(\d{4})-(\d{2})-(\d{2})'
text = '2021-11-23'

match = re.match(pattern, text)
if match:
    print('匹配成功:', match.group(1), match.group(2), match.group(3))
else:
    print('匹配失败')

反向引用

反向引用用于引用捕获组中的内容。

pattern = r'(\d{2})-(\d{2})-(\d{4})'
text = '23-11-2021'

match = re.match(pattern, text)
if match:
    print('匹配成功:', match.group(1), match.group(2), match.group(3))
    print('年份:', match.group(3)[2:])
else:
    print('匹配失败')

非捕获组

非捕获组用于匹配但不保存匹配结果。

pattern = r'(?:\d{2})-(\d{2})-(\d{4})'
text = '23-11-2021'

match = re.match(pattern, text)
if match:
    print('匹配成功:', match.group(1), match.group(2), match.group(3))
else:
    print('匹配失败')

前瞻断言与后瞻断言

前瞻断言和后瞻断言用于检查字符串中是否存在某种模式,而不保存匹配结果。

pattern = r'(?=\d{3}-\d{2}-\d{4})\d{2}-\d{2}-\d{4}'
text = '2021-11-23'

match = re.match(pattern, text)
if match:
    print('匹配成功:', match.group())
else:
    print('匹配失败')

贪婪与非贪婪模式

贪婪模式匹配尽可能多的字符,而非贪婪模式匹配尽可能少的字符。

pattern = r'(\d+) (\d+) (\d+)'
text = '123 456 7'

match = re.match(pattern, text)
if match:
    print('贪婪模式:', match.group())
    print('非贪婪模式:', match.group(1), match.group(2), match.group(3))
else:
    print('匹配失败')

正则表达式实战案例

电子邮件地址验证

pattern = r'^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$'
email = 'example@example.com'

if re.match(pattern, email):
    print('电子邮件地址有效')
else:
    print('电子邮件地址无效')

电话号码提取

pattern = r'\b\d{3}[-.]?\d{3}[-.]?\d{4}\b'
text = 'My phone number is 123-456-70.'

matches = re.findall(pattern, text)
print('匹配结果:', matches)

HTML标签清理

pattern = r'<[^>]+>'
text = '<html><body><p>Hello, world!</p></body></html>'

cleaned_text = re.sub(pattern, '', text)
print('清理后的文本:', cleaned_text)

总结

正则表达式是处理文本数据的一把利器,掌握正则表达式可以帮助我们高效地完成各种数据处理任务。本文介绍了正则表达式的核心概念、常用语法、高级技巧和实战案例,希望对您有所帮助。在实际应用中,不断练习和积累经验,您将能够更加熟练地运用正则表达式,实现完美匹配。