python正則表達式以及re模塊
元字符
正則表達式的語法就由表格中的元字符組成,一般用于搜索、替換、提取文本數據
元字符 | 含義 |
---|---|
. | 匹配除換行符以外的任何單個字符 |
* | 匹配前面的模式0次或1次 |
+ | 匹配前面的模式1次或多次 |
? | 匹配前面的模式0次或1次 |
[] | 用于定義字符集,匹配方括號內的任何字符 |
^ | 匹配字符串的開頭 |
$ | 匹配字符串的結尾 |
\ | 用于轉義特殊字符,使其失去特殊含義 |
[^] | 匹配不在字符集中的任何字符 |
| | 用于表示‘或’,匹配兩個或多個選擇之一 |
\d | 匹配任何數字字符 |
\D | 匹配任何非數字字符 |
\w | 匹配任何字母數字字符或下劃線 |
\W | 匹配任何非字母數字字符或下劃線 |
\s | 匹配任何空白字符 |
\S | 匹配任何非空白字符 |
re模塊
常用的re模塊內置方法:
re.方法名(表達式,文本數據)
re.search(pattern, string)
:從字符串中搜索匹配給定模式的第一個出現,并返回一個匹配對象。re.match(pattern, string)
:嘗試從字符串的開頭匹配給定模式,如果成功匹配,則返回一個匹配對象。re.findall(pattern, string)
:查找字符串中所有與給定模式匹配的非重疊部分,并返回一個列表。re.sub(pattern, replacement, string)
:在字符串中查找與給定模式匹配的部分,并用替換字符串替換它們。re.compile(pattern)
:將正則表達式模式編譯為一個正則表達式對象,以便進行復用和更高效的操作。
search()
從給定的字符串的開頭開始搜索,并在字符串中查找第一個與模式匹配的子字符串。它只返回第一個匹配的結果,并且不會查找后續的匹配
import repattern = 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: appleprint("Start:", match.start()) # Start: 10print("End:", match.end()) # End: 15
match()
與search()相似,match()是從字符串的開頭開始嘗試匹配給定的正則表達式模式
import repattern = r"apple"
string = "I have an apple and a banana"
match = re.match(pattern, string)
if match:print("Found:", match.group()) # Found: appleprint("Start:", match.start()) # Start: 10print("End:", match.end()) # End: 15
findall()
查找并返回字符串中與給定正則表達式模式匹配的所有非重疊子字符串
import repattern = r"\d+"
string = "There are 123 apples and 456 bananas"
matches = re.findall(pattern, string)
print("Matches:", matches) # 輸出: Matches: ['123', '456']
sub()
將搜索到的字符替換
import repattern = 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
compile()
用于將正則表達式模式編譯為一個可重復使用的正則表達式對象
import repattern = 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 remob = 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 repattern = 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 repattern = 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)
在大部分爬蟲案例中我們需要處理包含換行符的文本(當然現在爬蟲也不咋用正則了~)這時就會用到多行模式(Multiline Mode)
import repattern2 = r"^abc$"
string2 = "abc\n123\nabc"
matches2 = re.findall(pattern2, string2, re.MULTILINE)
print(matches2) # ['abc', 'abc']
(?P<>)
(?P…) 是正則表達式中的一個語法構造,用于給一個子模式(子表達式)命名,以便在匹配結果中可以通過名稱來引用
import repattern = r"(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})"
text = "Today's date is 2022-09-30."match = re.search(pattern, text)
if match:year = match.group("year")month = match.group("month")day = match.group("day")print(f"Year: {year}, Month: {month}, Day: {day}")