1. 程式人生 > >爬蟲筆記(六)——如何寫正則表示式詳解

爬蟲筆記(六)——如何寫正則表示式詳解

什麼是正則表示式?

  正則表示式(Regular Expression)是一種文字模式,在編寫處理字串的程式或網頁時,經常會有查詢符合某些規則的字串的需求。正則表示式就是用於描述這些規則的工具,換句話說,正則表示式就是記錄文字規則的程式碼。我們將分別從原子、元子符、模式修正符、貪婪模式與懶惰模式等方面進行介紹,程式碼引進re模組。

這篇部落格主要講如何寫正則表示式,下篇再介紹關於正則表示式的函式運用。

一、原子

原子是正則表示式中最基本的組成單位,每個正則表示式至少要包含一個原子,常見原子主要有以下幾類:

  1. 普通子符作為原子
  2. 非列印字元作為原子
  3. 通用字元作為原子
  4. 原子表

普通字元

就是利用數字、大小寫字母、下滑線等作為原子使用。如“python",這裡有六個原子,分別是python的六個字母。如下面的程式碼中,用”python"取匹配一段字元,如“wanglongxuepython",成功匹配到了'python'。

import re

string = "wanglongxuepython"
pattern = "python"
result = re.search(pattern,string)
print (result)

#<_sre.SRE_Match object; span=(11, 17), match='python'>

非列印字元就是指在字串中起格式控制的符號,常見有換行符\n和製表符\t,其分別用來匹配換行和製表。

import re

string = '''wanglong
xuepython'''
pattern = "\n"
result = re.search(pattern,string)
print (result)

#<_sre.SRE_Match object; span=(8, 9), match='\n'>

如果string沒有包含換行,就會返回None。

import re

string = "wanglongxuepython"
pattern = "\n"
result = re.search(pattern,string)
print (result)

#None

通用字元就是可以用一個原子匹配一類字元,常見的通用字元有以下幾個:

  1. \w             可以匹配任意一個大小寫字母、數字或下劃線的字元
  2. \W     可以匹配任意一個除大小寫字母、數字和下劃線以外的字元
  3. \s     可以匹配任意一個空白字元
  4. \S     可以匹配任意一個除空白字元以外的字元
  5. \d     可以匹配任意一個十進位制數
  6. \D     可以匹配任意一個除十進位制數以外的字元  

比如我們用"\d\dxue\w"去匹配一個string"wanglong1314xuepython",就可以得到“14xuep"。

import re

string = "wanglong1314xuepython"
pattern = "\d\dxue\w"
result = re.search(pattern,string)
print (result)

#<_sre.SRE_Match object; span=(10, 16), match='14xuep'>

原子表就是定義一組地位平等的原子,然後匹配時會在原子表中取任意一個原子,用[ ]表示,比如[love]。還有一種是匹配時會取除原子表內原子以外任意一個,這種用[ ^]表示,比如[^love]。[a-z]表示是a到z。

import re

string = "wanglong1314xuepython"
pattern = "[love]ong13"
result = re.search(pattern,string)
print (result)

#<_sre.SRE_Match object; span=(4, 10), match='long13'>

二、元字元

所謂的元字元就是在正則表示式中具有特殊含義的字元,比如重複前面N次字元等。具體來說元字元分為任意匹配元字元、邊界限制元字元、限定符、模式選擇符、模式單元等。

任意匹配元字元用著'.'表示,他可以匹配除換行符以外的任意一個字元。

import re

string = "wanglong1314xuepython"
pattern = "...long...."
result = re.search(pattern,string)
print (result)

#<_sre.SRE_Match object; span=(1, 12), match='anglong1314'>

邊界限制元字元,可以使用"^"匹配字串的開始,使用"$"匹配字串的結束。

import re

string = "wanglong1314xuepython"
pattern1 = "^wang"
pattern2 = "^long"
pattern3 = "thon$"
pattern4 = "pyth$"
result1 = re.search(pattern1,string)
result2 = re.search(pattern2,string)
result3 = re.search(pattern3,string)
result4 = re.search(pattern4,string)
print (result1)
print (result2)
print (result3)
print (result4)

#<_sre.SRE_Match object; span=(0, 4), match='wang'>
#None
#<_sre.SRE_Match object; span=(17, 21), match='thon'>
#None

限定符也是元字元的一種,常見限定符有下面幾個:

  1. *                 匹配0次、1次或多次前面的原子
  2. ?      匹配0次或1次前面的原子
  3. +      匹配1次或多次前面的原子 
  4. {n}      前面的原子恰好出現n次
  5. {n,}      前面的原子至少出現n次
  6. {n,m}      前面的原子至少出現n次,至多出現m次
import re

string = "aabbbcde"
pattern1 = "a.*c"
pattern2 = "b?c"
pattern3 = "b+c"
pattern4 = "b{2}c"
pattern5 = "b{2,}c"
result1 = re.search(pattern1,string)
result2 = re.search(pattern2,string)
result3 = re.search(pattern3,string)
result4 = re.search(pattern4,string)
result5 = re.search(pattern5,string)
print (result1)
print (result2)
print (result3)
print (result4)
print (result5)

#<_sre.SRE_Match object; span=(0, 6), match='aabbbc'>
#<_sre.SRE_Match object; span=(4, 6), match='bc'>
#<_sre.SRE_Match object; span=(2, 6), match='bbbc'>
#<_sre.SRE_Match object; span=(3, 6), match='bbc'>
#<_sre.SRE_Match object; span=(2, 6), match='bbbc'>

模式選擇符用著‘|’表示,比如' A|B ',它可以任意選擇一種模式去匹配,即A模式和B模式,哪種模式更快匹配到則取哪種模式。

import re

string = "aabbbcde"
pattern1 = "ac|cd"
pattern2 = "cd|aa"
result1 = re.search(pattern1,string)
result2 = re.search(pattern2,string)
print (result1)
print (result2)

#<_sre.SRE_Match object; span=(5, 7), match='cd'>
#<_sre.SRE_Match object; span=(0, 2), match='aa'>

模式單元符用()表示,他可以將幾個單元符變成一個大單元。

import re

string = "aabbbbcde"
pattern1 = "(bb){2}cd"
pattern2 = "bb{2}cd"
result1 = re.search(pattern1,string)
result2 = re.search(pattern2,string)
print (result1)
print (result2)

#<_sre.SRE_Match object; span=(2, 8), match='bbbbcd'>
#<_sre.SRE_Match object; span=(3, 8), match='bbbcd'>

三、模式修正

所謂的模式修正就是在不改變正則表示式的情況下,通過模式修正改變正則表示式的含義,從而實現一些匹配結果調整等功能。常見的一些模式修正符有以下幾點:

  1. I             匹配時忽略大小寫
  2. M   多行匹配
  3. L   做本地識別匹配
  4. U   根據Unicode字元及解析字元
  5. S   讓.可以匹配換行符,即.可以匹配任意字元
import re

string = "aabbbbcde"
pattern1 = "bbBB"
result1 = re.search(pattern1,string)
result2 = re.search(pattern1,string,re.I)
print (result1)
print (result2)

#None
#<_sre.SRE_Match object; span=(2, 6), match='bbbb'>

四、貪婪模式與懶惰模式

貪婪模式的核心就是儘可能地多的匹配,懶惰模式的核心就是儘可能地少匹配。

import re

string = "wanglongphp223python_py"
pattern1 = "p.*y"  #貪婪模式
pattern2 = "p.*?y" #懶惰模式
result1 = re.search(pattern1,string)
result2 = re.search(pattern2,string)
print (result1)
print (result2)

#<_sre.SRE_Match object; span=(8, 23), match='php223python_py'>
#<_sre.SRE_Match object; span=(8, 16), match='php223py'>