1. 程式人生 > 其它 >所有字元不含換行 正則表示式_網路爬蟲 | 正則表示式

所有字元不含換行 正則表示式_網路爬蟲 | 正則表示式

技術標籤:所有字元不含換行 正則表示式

正則表示式中匹配與查詢

正則表示式,簡稱為regex,是文字模式的描述方法。

>>>importre
>>>pattern=re.compile('\d\d\d-\d\d\d-\d\d\d\d')
>>>phone=pattern.search('Callmeat415-555-1011tomorrow')
>>>phone.group()#通過group返回匹配的結果
'415-555-1011'

compile()

Python中所有正則表示式的函式都在re模組中,向re.compile()

傳入一個字串值,表示正則表示式,它將返回一個regex模式物件。

regex物件search()方法查詢傳入的字串,尋找該正則表示式的所有匹配。

如果字串中沒有找到該正則表示式模式,search()方法將返回None。如果找到了該模式,search()方法將返回一個match對

re.compile(pattern[,flags])

pattern : 一個字串形式的正則表示式

flags 可選,表示匹配模式,比如忽略大小寫,多行模式等,具體引數為:

  • re.I忽略大小寫
  • re.L表示特殊字符集\w, \W, \b, \B, \s, \S依賴於當前環境
  • re.M 多行模式
  • re.S 即為' . '
    並且包括換行符在內的任意字元(' . '不包括換行符)
  • re.U 表示特殊字符集 \w, \W, \b, \B, \d, \D, \s, \S依賴於 Unicode 字元屬性資料庫
  • re.X 為了增加可讀性,忽略空格和' # '後面的註釋

search()

另一種方法,直接使用re.search()方法,掃描整個字串並返回第一個成功的匹配。

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

pattern: 匹配的正則表示式轉換而來的字串。

string: 要匹配的字串。

flags: 可選引數,標誌位,用於控制正則表示式的匹配方式,如:是否區分大小寫,多行匹配等等。


group()

search物件可以使用group(num) 或 groups() 匹配物件函式來獲取匹配表示式,它返回被查詢字串中實際匹配的文字。

匹配物件方法描述
group(num=0)匹配的整個表示式的字串,group() 可以一次輸入多個組號,可以取得匹配文字的不同部分,在這種情況下它將返回一個包含那些組所對應值的元組。
groups()返回一個包含所有小組字串的元組,從 1 到 所含的小組號。

利用括號分組,如將區號從電話號碼中分離,新增括號將在正則表示式中建立"分組"。

(\d\d\d)-(\d\d\d-\d\d\d\d),然後可以使用group()匹配物件方法,從一個分組中獲取匹配的文字。第一對括號是第1組。第二對括號是第2組。

>>>pattern=('(\d\d\d)-(\d\d\d-\d\d\d\d)')
>>>phone=re.search(pattern,'Callmeat415-555-1011tomorrow')

>>>phone.group(0)#返回所有匹配的文字
'455-555-1011'
>>>phone.group(1)#返回第一個括號內容
'455'
>>>phone.group(2)#返回第二個括號內容
'555-1011'
>>>phone.groups()#返回的是元組
('455','555-1011')

用管道匹配多個分組

字元|稱為"管道"。希望匹配許多表達式中的一個時,就可以使用它。例如,正則表示式r'Jim|雲朵'將匹配'Jim'或'雲朵'。如果都出現在被查詢的字串中,則匹配第一次出現的文字。

>>>pattern=(r'Jim|yunduo')
>>>match=re.search(pattern,'yunduoistheauthorofDATASTUDIO')
>>>match.group()#第一次出現的匹配文字
'yunduo'

用問號實現可選匹配

不論這段文字在不在,正則表示式都會認為匹配。字元?表明它前面的分組在這個模式中是可選的。

>>>pattern=re.compile(r'(\d\d\d-)?\d\d\d-\d\d\d\d')#包含或者不包含區號
>>>phone=pattern.search('Mynumberis415-555-1011')#有區號
>>>phone.group()
'415-555-1011'
>>>phone=pattern.search('Mynumberis555-1011')#有區號
>>>phone.group()
'555-1011'

用星號匹配零次或多次

  • *(稱為星號)意味著"匹配零次或多次",即星號之前的分組,可以在文字中出現任意次。它可以完全不存在,或一次又一次地重複。

  • +(加號)則意味著"匹配一次或多次"。星號不要求分組出現在匹配的字串中,但加號不同,加號前面的分組必須"至少出現一次"。

>>>pattern=(r'DA(TA)*STUDIO')
>>>match=re.search(pattern,'DATATATATASTUDIO')
>>>match.group()
'DATATATATASTUDIO'
>>>match=re.search(pattern,'DASTUDIO')
>>>match.group()
'DASTUDIO'

>>>pattern=(r'DA(TA)+STUDIO')#至少出現一次
>>>match=re.search(pattern,'DASTUDIO')
>>>match.group()
----------------------------------------------------
AttributeErrorTraceback(mostrecentcalllast)
-122-4009f4d8d45b>in1pattern=(r'DA(TA)+STUDIO')#至少出現一次2match=re.search(pattern,'DASTUDIO')
---->3match.group()
AttributeError:'NoneType'objecthasnoattribute'group'

用花括號匹配特定次數

如果想要一個分組重複特定次數,就在正則表示式中該分組的後面,跟上花括號包圍的數字。例如,正則表示式(Ha){3}將匹配字串'HaHaHa',但不會匹配'HaHa'

可以指定一個範圍,即在花括號中寫下一個最小值、一個逗號和一個最大值。例如,正則表示式(Ha){3,5}將匹配'HaHaHa'、'HaHaHaHa'和'HaHaHaHaHa'

貪婪與非貪婪

如果需要匹配一段包含各種不同型別資料的字串,傳統方法需要挨個去匹配,而使用.*可以匹配所有字元,是一種萬能匹配的方式。

  • 正則表示式預設是貪婪的,儘可能匹配最長的字串

  • 另一種為非貪婪模式:加問號'?',儘可能匹配最短的字元

>>>haRegex=re.compile(r'(ha){3}')
>>>match=haRegex.search('hahahahha')
>>>match.group()
'hahaha'

>>>haRegex=re.compile(r'(ha){3,5}')
>>>match=haRegex.search('hahahahaha')#貪婪模式,儘可能長的匹配
>>>match.group()
'hahahahaha'

>>>haRegex=re.compile(r'(ha){3,5}?')
>>>match=haRegex.search('hahahahaha')#非貪婪模式,儘可能短的匹配
>>>match.group()
'hahaha'

點'.' 星'*'匹配所有字元

  • . ---- 匹配任意字元,除換行
  • * ---- 匹配零個或者多個表示式
  • .* ---- 匹配任意零個或者多個字元
  • .*? ---- 匹配任意零個或者多個字元,非貪婪模式

\n 換行符是需要用跨行匹配

  • (.,re.DOTALL):匹配任意字元,包括換行
#點匹配任意一個字元
>>>regex=re.compile(r'<.>')
>>>match=regex.search('STUIO')
>>>match.group()
''

#點星匹配任意字元
>>>regex=re.compile(r'<.>')
>>>match=regex.search('STUDIO')
>>>match.group()
''

#點星問號匹配任意字元,非貪婪匹配
>>>regex=re.compile(r'<.>')
>>>match=regex.search('STUlovedata>DIO')
>>>match.group()
''

#跨行匹配
>>>regex=re.compile(r'<.>',re.DOTALL)
>>>text='''data...dio>yunduo'''
>>>match=regex.search(text)
>>>match.group()
''

findall()方法匹配所有內容

在字串中找到正則表示式所匹配的所有子串,並返回一個列表,如果沒有找到匹配的,則返回空列表。

re.findall(pattern,string,flags=0)
pattern.findall(string[,pos[,endpos]])

pattern 匹配模式,由要匹配的正則表示式轉換而來

string 待匹配的字串。

flags 可選引數,標誌位,用於控制正則表示式的匹配方式,如:是否區分大小寫,多行匹配等等。

pos 可選引數,指定字串的起始位置,預設為 0。

endpos 可選引數,指定字串的結束位置,預設為字串的長度。


#findall()匹配多個,返回的是列表
regex=re.compile(r'\d+')
regex.findall('one1two2three33four4444')
['1','2','33','4444']

匹配字串邊界

如果字串在開始處、結尾處,或者字串的分界符為空格、標點符號以及換行,可以使用\b 匹配字串邊界。

#需要匹配兩側均為邊界
#左側為邊界,右側不是邊界
>>>regex=re.compile(r'\bdata\b')
>>>match=regex.search('datastudio')
>>>print(match)
None

#左側為邊界,右側是空格
>>>regex=re.compile(r'\bdata\b')
>>>match=regex.search('datastudio')
>>>print(match)
0,4),match='data'>#左側為空格,右側不是邊界>>>regex=re.compile(r'\bdata\b')>>>match=regex.search('datastudio')>>>print(match)None#左側是邊界,右側是符號點>>>regex=re.compile(r'\bdata\b')>>>match=regex.search('data.studio')>>>print(match)0,4),match='data'>

匹配所有指定字元開頭的字串

>>>pattern='data_\w+'
>>>string='關注DATA_STUDIODATA_STUDIOdata_studio'
>>>match=re.findall(pattern,string,re.I)#搜尋字串,不區分大小寫
>>>print(match)
['DATA_STUDIO','data_studio']

re模組中的字元處理

re.sub()

re.sub用於替換字串中的匹配項,即將某個字串中所有匹配正則表達的部分替換成其他字串。

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

pattern : 正則中的模式字串,由要匹配的正則表示式轉換而來。

repl : 替換的字串,也可為一個函式。

string : 要被查詢替換的原始字串。

count : 模式匹配後替換的最大次數,預設 0 表示替換所有的匹配。

flags : 編譯時用的匹配模式,數字形式。可選引數,用於控制正則表示式的匹配方式,如:是否區分大小寫,多行匹配等等。


#替換字串
>>>importre
>>>pattern=r'1[3456789]\d{9}'
>>>string='電話號碼為:18188888888 的提取碼為:12345678'
>>>match=re.sub(pattern,'1**********',string)
>>>print(match)
'電話號碼為:1**********的提取碼為:12345678'

#刪除多餘字串
>>>string='a1l8l18kh8oo888oo8ool8lll8'
>>>pattern='[a-z]'
>>>match=re.sub(pattern,"",string,flags=re.I)
#匹配字串,將所有字母替換為空,並區分大小寫
>>>
print(match)
18188888888

re.split()

split 方法按照能夠匹配的子串將字串分割後返回列表。

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

pattern 正則中的模式字串,由要匹配的正則表示式轉換而來。

string 要被查詢替換的原始字串。

maxsplit 分隔次數,maxsplit=1 分隔一次,預設為 0,不限制次數。如若需要分割的字串非常大,並且不希望窮盡分割,可使用此引數。

flags 編譯時用的匹配模式,數字形式。可選引數,用於控制正則表示式的匹配方式,如:是否區分大小寫,多行匹配等等。


>>>importre
>>>pattern=r'[?|&]'
>>>url='http://httpbin.org/get?name="Jim"&age=18'
>>>match=re.split(pattern,url)
>>>print(result)
['http://httpbin.org/get','name="Jim"','age=18']

附錄常見匹配

字元描述
\將下一個字元標記為一個特殊字元、或一個原義字元、或一個 向後引用、或一個八進位制轉義符。例如,'n' 匹配字元 "n"。'\n' 匹配一個換行符。序列 '\' 匹配 "" 而 "(" 則匹配 "("。
^匹配輸入字串的開始位置。如果設定了 RegExp 物件的 Multiline 屬性,^ 也匹配 '\n' 或 '\r' 之後的位置。
$匹配輸入字串的結束位置。如果設定了RegExp 物件的 Multiline 屬性,$ 也匹配 '\n' 或 '\r' 之前的位置。
*匹配前面的子表示式零次或多次。例

獲取更多常見匹配字元及描述,可關注公眾號並回復" 正則表示式 "獲取
-- 資料STUDIO --

13a49d37d26efca1e1f0c775e8a88d4e.gif