正则表达式的语法就由表格中的元字符组成,一般用于搜索、替换、提取文本数据
元字符 | 含义 |
---|---|
. | 匹配除换行符以外的任何单个字符 |
* | 匹配前面的模式0次或1次 |
+ | 匹配前面的模式1次或多次 |
? | 匹配前面的模式0次或1次 |
[] | 用于定义字符集,匹配方括号内的任何字符 |
^ | 匹配字符串的开头 |
$ | 匹配字符串的结尾 |
\ | 用于转义特殊字符,使其失去特殊含义 |
[^] | 匹配不在字符集中的任何字符 |
| | 用于表示‘或’,匹配两个或多个选择之一 |
\d | 匹配任何数字字符 |
\D | 匹配任何非数字字符 |
\w | 匹配任何字母数字字符或下划线 |
\W | 匹配任何非字母数字字符或下划线 |
\s | 匹配任何空白字符 |
\S | 匹配任何非空白字符 |
常用的re模块内置方法:
re.方法名(表达式,文本数据)
re.search(pattern, string)
:从字符串中搜索匹配给定模式的第一个出现,并返回一个匹配对象。re.match(pattern, string)
:尝试从字符串的开头匹配给定模式,如果成功匹配,则返回一个匹配对象。re.findall(pattern, string)
:查找字符串中所有与给定模式匹配的非重叠部分,并返回一个列表。re.sub(pattern, replacement, string)
:在字符串中查找与给定模式匹配的部分,并用替换字符串替换它们。re.compile(pattern)
:将正则表达式模式编译为一个正则表达式对象,以便进行复用和更高效的操作。从给定的字符串的开头开始搜索,并在字符串中查找第一个与模式匹配的子字符串。它只返回第一个匹配的结果,并且不会查找后续的匹配
import re
pattern = r"apple"
string = "I have an apple and a banana"
match = re.search(pattern, string)
if match:
print(type(match)) # <class 're.Match'>
print("Found:", match.group()) # Found: apple
print("Start:", match.start()) # Start: 10
print("End:", match.end()) # End: 15
与search()相似,match()是从字符串的开头开始尝试匹配给定的正则表达式模式
import re
pattern = r"apple"
string = "I have an apple and a banana"
match = re.match(pattern, string)
if match:
print("Found:", match.group()) # Found: apple
print("Start:", match.start()) # Start: 10
print("End:", match.end()) # End: 15
查找并返回字符串中与给定正则表达式模式匹配的所有非重叠子字符串
import re
pattern = r"\d+"
string = "There are 123 apples and 456 bananas"
matches = re.findall(pattern, string)
print("Matches:", matches) # 输出: Matches: ['123', '456']
将搜索到的字符替换
import re
pattern = r"apple"
string = "I have an apple and a banana"
replacement = "orange"
new_string = re.sub(pattern, replacement, string)
print(new_string) # I have an orange and a banana
用于将正则表达式模式编译为一个可重复使用的正则表达式对象
import re
pattern = r"\d+"
string = "There are 123 apples and 456 bananas"
regex = re.compile(pattern)
matches = regex.findall(string)
print(matches) # ['123', '456']
以下是用()分组的正则表达式模式
group()中的参数可以提取分组后的数据的索引,但这个索引是从1开始的,为空则返回全部
import re
mob = re.compile(r'(\+86)(\d\d\d)(\d\d\d\d)(\d\d\d\d)')
phone_number1 = mob.search('我的电话号码是+8618900043210')
print('电话号码' + phone_number1.group()) # 电话号码+8618900043210
print('前缀' + phone_number1.group(1)) # 前缀+86
print('前三位' + phone_number1.group(2)) # 前三位189
print('中四位' + phone_number1.group(3)) # 中四位0004
print('后四位' + phone_number1.group(4)) # 后四位3210
默认情况下,正则表达式使用贪婪匹配。它会尽可能多地匹配字符。
在贪婪模式下,量词后面没有添加?
时,它会匹配尽可能长的字符串。非贪婪模式则反之
例如,对于正则表达式 a.*b
和字符串 aabab
,贪婪匹配将匹配整个字符串 "aabab"
,而非贪婪模式仅仅是第一个 "aab"
。
import re
# 贪婪匹配示例
pattern1 = r'a.*b'
pattern2 = r'a.*?b'
string = 'aabab'
match1 = re.search(pattern1, string)
match2 = re.search(pattern2, string)
print(f"贪婪模式:{match1.group()}") # 贪婪模式:aabab
print(f"非贪婪模式:{match2.group()}") # 非贪婪模式:aab
^表示匹配字符串的开头。当 ^
放置在正则表达式的开头时,它表示要匹配的内容必须出现在字符串的开头位置
import re
pattern = r'^(aaa)(\d+)'
regex = re.compile(pattern)
match1 = regex.search('aaa666这是信息的格式')
match2 = regex.search('信息的格式是aaa666')
print(match1.group()) # aaa666
print(type(match2)) # <class 'NoneType'>
可以看到当开头不存在^所匹配的字符串时就会采不到数据
同理$就是表示匹配字符串的结尾,它可以用来检查一个字符串是否以特定的模式结束
import re
pattern = r'(aaa)(\d+)$'
regex = re.compile(pattern)
match1 = regex.search('aaa666这是信息的格式')
match2 = regex.search('信息的格式是aaa666')
print(type(match1)) # <class 'NoneType'>
print(match2.group()) # aaa666
在大部分爬虫案例中我们需要处理包含换行符的文本(当然现在爬虫也不咋用正则了~)这时就会用到多行模式(Multiline Mode)
import re
pattern2 = r"^abc$"
string2 = "abc\n123\nabc"
matches2 = re.findall(pattern2, string2, re.MULTILINE)
print(matches2) # ['abc', 'abc']