作者: LIANG,Southampton, UK.

当涉及到处理文本数据时,正则表达式(通常缩写为"regex"或"re")是一种非常强大的工具,它可以用来在文本中进行模式匹配、搜索和替换操作。Python中有一个内置的re模块,它提供了用于处理正则表达式的函数和类。

特别的,从一些文本文件提取数据并转换为浮点型时,正则化表达式就会派上大用场。以下是正则化表达式的常用函数与功能。

1. 字符匹配

1.1 特殊字符

.: 匹配任意单个字符(除了换行符)。
\d: 匹配任意数字字符。
\w: 匹配任意字母数字下划线字符。
\s: 匹配任意空白字符(空格、制表符、换行等)。

1.2 重复

*: 匹配前一个字符0次或多次。
+: 匹配前一个字符1次或多次。
?: 匹配前一个字符0次或1次。
{n}: 匹配前一个字符恰好n次。
{n, m}: 匹配前一个字符至少n次,最多m次。

1.3字符类匹配

[abc]: 匹配a、b或c中的任意一个字符。
[^abc]: 匹配除了a、b、c以外的任意字符。

1.4 边界匹配

^: 匹配字符串的开头。
$: 匹配字符串的结尾。
\b: 匹配单词边界。

1.5 分组匹配

(): 分组匹配,使用括号进行分组的话,正则表达式单独匹配()里面的内容,之后再按照规则匹配后面的内容。这点比较难理解,举例说明:

import re

pattern = r"(\w+)\s(\d+)"  # 匹配由字母和数字组成的单词,后跟一个数字
text = "There are 3 apples and 5 bananas."
matches = re.findall(pattern, text)
print(matches)  # 输出: [('There', '3'), ('bananas', '5')]
# **********************************************************
pattern = r"\w+\s\w+\s\d+"  # 匹配两个单词后跟一个数字
text = "There are 3 apples and 5 bananas."
matches = re.findall(pattern, text)
print(matches)  # 输出: ['There are 3']

上述例子详细说明了使用分组()不使用分组()的区别,简单来说,就是先匹配一块,再匹配一块。

1.6 分类匹配

在Python的re模块中,方括号[]用于创建字符类(character class),它用来匹配其中的任意一个字符。字符类可以包含多个字符或字符范围,用来指定匹配的字符集合。

  • 单个字符匹配: 可以在字符类中列出单个字符,它将匹配这些字符中的任意一个。
import re

pattern = r"[aeiou]"  # 匹配任意一个元音字母
text = "apple"
matches = re.findall(pattern, text)
print(matches)  # 输出: ['a', 'e']
  • 字符范围匹配: 可以使用连字符 - 来指定一个字符范围
pattern = r"[a-z]"  # 匹配任意一个小写字母
text = "Hello"
matches = re.findall(pattern, text, re.IGNORECASE)
print(matches)  # 输出: ['H', 'e', 'l', 'l', 'o']
  • 排除字符匹配: 可以使用 ^ 在字符类的开头,来指定排除某些字符。
pattern = r"[^0-9]"  # 匹配任意一个非数字字符
text = "abc123"
matches = re.findall(pattern, text)
print(matches)  # 输出: ['a', 'b', 'c']
  • 组合多个字符类: 可以组合多个字符类,以获取更复杂的匹配。
pattern = r"[A-Za-z0-9]"  # 匹配任意一个字母或数字
text = "Hello123"
matches = re.findall(pattern, text)
print(matches)  # 输出: ['H', 'e', 'l', 'l', 'o', '1', '2', '3']

上述介绍的正则化字符匹配能够处理绝大多数任务,更多用法请参考官网:正则化表达式语法

2. re的使用

re 模块是Python中用于正则表达式操作的内置模块,下面介绍其常用函数及功能。

2.1 re.match(pattern, string, flags=0):

从字符串的开头开始匹配模式。如果模式在字符串开头匹配成功,就返回一个匹配对象,否则返回None

import re

pattern = r"hello"
text = "hello, world!"
match_result = re.match(pattern, text, re.IGNORECASE)
if match_result:
    print("Match found:", match_result.group())
else:
    print("No match")

2.2 re.search(pattern, string, flags=0)

在字符串中搜索匹配模式的第一个位置。如果匹配成功,返回一个匹配对象;否则返回None

import re

pattern = r"world"
text = "Hello, world!"
search_obj = re.search(pattern, text)
if search_obj:
    print("Match found:", search_obj.group())
else:
    print("No match")

2.3 re.findall(pattern, string, flags=0)

返回一个包含所有匹配子串的列表。

import re

pattern = r"\d+"
text = "There are 123 apples and 456 bananas."
matches = re.findall(pattern, text)
print(matches)  # 输出: ['123', '456']

2.4 re.finditer(pattern, string, flags=0)

返回一个迭代器,包含所有匹配的迭代对象。

import re

pattern = r"\d+"
text = "There are 123 apples and 456 bananas."
match_iter = re.finditer(pattern, text)
for match in match_iter:
    print("Match found:", match.group())
# 输出:
# Match found: 123
# Match found: 456

2.5 re.fullmatch(pattern, string, flags=0)

尝试将整个字符串与模式匹配。如果匹配成功,返回一个匹配对象;否则返回None

import re

pattern = r"\d+"
text = "123"
full_match_obj = re.fullmatch(pattern, text)
if full_match_obj:
    print("Full match:", full_match_obj.group())
else:
    print("No match")
# 输出: Full match: 123

2.6 re.split(pattern, string, maxsplit=0, flags=0)

使用模式分割字符串,并返回分割后的子串列表。

import re

pattern = r"\s"
text = "Hello world!"
split_result = re.split(pattern, text)
print(split_result)
# 输出: ['Hello', 'world!']

2.7 re.sub(pattern, repl, string, count=0, flags=0)

使用替换字符串 repl 替换字符串中的模式匹配。可以指定 count 来限制替换次数。

import re

pattern = r"\d+"
text = "I have 3 apples and 5 bananas."
new_text = re.sub(pattern, "X", text)
print(new_text)
# 输出: I have X apples and X bananas.

2.8 re.subn(pattern, repl, string, count=0, flags=0)

与re.sub()类似,但返回替换后的新字符串和替换次数。

import re

pattern = r"\d+"
text = "I have 3 apples and 5 bananas."
new_text, num_replacements = re.subn(pattern, "X", text)
print(new_text)
# 输出: I have X apples and X bananas.
print("Number of replacements:", num_replacements)
# 输出: Number of replacements: 2

其他不常用函数请参考官网更多示例