1. 程式人生 > >筆記_正則表示式_1

筆記_正則表示式_1

正則表示式

動機:

1.文字處理已經成為計算機常見的工作之一 2.對文字內容的搜尋,定位,提取 3.為了方便的解決上述問題,產生了正則表示式技術

定義:

即文字的高階匹配模式,提供搜尋,替換等功能。其本質是一系列由特殊符號組成的字串, 這個字串就是正則表示式(簡稱re)。

目標:

1.熟練掌握正則表示式符號 2.讀懂常見的正則表示式,編寫基本的搜尋提取功能正則 3.能夠熟練使用re模組操作正則表示式

正則表示式的特點

  • 方便文字處理
  • 支援的語言眾多
  • 使用靈活變化

python --> re模組

re.findall(pattern, string) 功能: 提取所有的正則匹配內容 引數: pattern 正則表示式     string 目標字串 返回值: 列表,所有提取到的內容

元字元的使用

1.普通字元

元字元: a B c 匹配規則: 每個字元匹配對應的字元

  In [4]: re.findall('ab','abchdgf')
  Out[4]: ['ab']

2.或

元字元 : |

  In [5]: re.findall('ab|ef','abchdgefgg')
  Out[5]: ['ab', 'ef']

  In [6]: re.findall('ab|bc','abcgggg')
  Out[6]: ['ab'] #重疊的部分,取不出

  In [7]: re.findall('ab | ef','abchdgefgg')
  Out[
7]: [] #空格也會被識別,不能隨意加空格

3.匹配單個字元

元字元: . 匹配規則: 匹配除換行外

In [8]: re.findall(‘f.o’,‘foo fao’) Out[8]: [‘foo’, ‘fao’]

In [9]: re.findall(‘f…d’,‘food fao’) Out[9]: [‘food’]

4.匹配字串開始位置

元字元: ^ 匹配規則:匹配字串的開始位置

In [13]: re.findall(’^Hello’,‘Hello Jay’) Out[13]: [‘Hello’]

In [14]: re.findall(’^Hello’,‘Jay Hello’) Out[14]: []

5.匹配字串開始位置

元字元: $ 匹配規則:匹配字串的結尾位置

In [16]: re.findall(‘Hello$’,‘Jay Hello’) Out[16]: [‘Hello’]

In [17]: re.findall(‘Hello$’,‘Jay Hello haha’) Out[17]: []

6.匹配重複

元字串: * 匹配規則: 匹配前面的字元重複 0 次或者多次 fo* 重複0次,> f fo* 重複多次,> fooo

In [18]: re.findall(‘fo*’,‘fooofaaaafoaaafoo’) Out[18]: [‘fooo’, ‘f’, ‘fo’, ‘foo’]

7.匹配重複

元字元: + 匹配規則: 匹配前面的字元重複1次或者多次 fo* 重複1次,> fo fo* 重複多次,> fooo

In [19]: re.findall(‘fo+’,‘fooofaaaafoaaafoo’) Out[19]: [‘fooo’, ‘fo’, ‘foo’]

8.匹配重複

字串: ? 匹配規則: 匹配前面的字元出現 0 次或 1 次

In [22]: re.findall(‘fo?’,‘fooooooaaafdddfo’) Out[22]: [‘fo’, ‘f’, ‘fo’]

9.匹配重複

元字元: {n} 匹配規則: 匹配前一個字元重複指定字數 fo{3} > fooo

In [24]: re.findall(‘fo{3}’,‘fooooooaaafdddfo’) Out[24]: [‘fooo’]

10.匹配重複

元字元: {m,n} 匹配規則: 匹配前面的字元出現 m–n 次 fo{2,4} > foo  fooo  foooo

In [25]: re.findall(‘fo{2,3}’,‘fooooooaaafoodddfo’) Out[25]: [‘fooo’, ‘foo’]

11.匹配字符集

字符集: [字符集] 匹配規則: 匹配字符集中的任意【一個】(不能連在一起)字元 [abc123] > 可匹配a b c 1 2 3 [a-zA-Z] > 可匹配從a到z,和A到Z之間的任意一個字元

匹配句子中以大寫字母開頭的單詞 In [26]: re.findall(’[A-Z]+[a-z]*’,‘This is my Jay’) Out[26]: [‘This’, ‘Jay’]

12.匹配字符集

字符集: [^…] 匹配規則: 匹配除了字符集中的任意一個字元一次或多次 [^abc] > 除了a/ b /c外的任意字元都可匹配

In [33]: re.findall(’[^ ]+’,‘This in my Jay’) #除空格外的… Out[33]: [‘This’, ‘in’, ‘my’, ‘Jay’] In [34]: re.findall(’[^0-9]+’,‘10+9-1=18’) #除數字外的… Out[34]: [’+’, ‘-’, ‘=’]

13.匹配任意(非)數字

元字元: \d   \D 匹配規則: \d 匹配任意數字字元,[0-9]       \D 匹配任意非數字字元,[^0-9]

In [35]: re.findall(‘1[\d]{10}’,‘18872075623 110112’) #匹配出1開頭的11位電話號碼… Out[35]: [‘18872075623’]

14.匹配任意(非)普通字元

元字元: \w   \W 匹配規則: \w 匹配任意普通字元: [_0-9a-zA-Z]也能匹配漢字        \W 匹配任意非普通字元

In [36]: re.findall(’[\w]+’,‘my$zui-#aide–jay’) Out[36]: [‘my’, ‘zui’, ‘aide’, ‘jay’] In [37]: re.findall(’[\W]+’,‘my$zui-#aide–jay’) Out[37]: [’$’, ‘-#’, ‘–’]

15.匹配任意(非)空字元

元字元 : \s 匹配任意空字元 [\r\t\n\v\f] \S 匹配任意非空字元

In [38]: re.findall("\w+\s+\w+",“hello world”) Out[38]: [‘hello world’] In [39]: re.findall("\S+",“hello this is tom”) Out[39]: [‘hello’, ‘this’, ‘is’, ‘tom’]

16.匹配字串位置

元字元 : \A \Z 匹配規則: \A 匹配字串開頭位置 ,同 ^ \Z 匹配字串結尾位置 ,同 $

*絕對匹配 :

當正則表示式前有^(或\A),最後有$(或\Z)時,那麼這個正則表示式一定是要匹配目標字串的全部內容。否則就什麼都不匹配。

In [38]: re.findall("\A\d+\Z",“123445”) Out[38]: [‘123445’] In [39]: re.findall("\A\d+\Z","123445 ") Out[39]: []

17.匹配(非)單詞邊界

元字元 : \b  \B 匹配規則 : \b 匹配單詞邊界位置 (普通字元和非普通字元交界認為是單詞邊界)       \B 匹配非單詞邊界位置

In [40]: re.findall(r"\bis\b",“this is Jay”) Out[40]: [‘is’]

元字元總結

匹配單個字元: . […] [^…] \d \D \w \W  \s \S    匹配重複: * + ? {n} {m,n} 匹配位置: ^ $ \A \Z \b \B 其他 : | () \

正則表示式轉義

正則中的特殊符號:. * + ? ^ $ [] {} () | \ 在正則表示式中,如果匹配特殊字元需要加 \ 作為轉義

eg.: 匹配.  需要使用.

python字串   正則   目標字串 '\\$\\d+'   \$\d+   $10

raw字串 : 不對字串內容進行轉義處理 '\\$\\d+'   ==>  r'\$\d+'

貪婪與非貪婪

  • 貪婪模式: 正則表示式的重複匹配預設總是儘可能的向後匹配更多的內容。 * + ? {m,n}

  • 非貪婪(懶惰)模式 : 儘可能少地匹配重複內容。

貪婪 -->> 非貪婪 *? +? ?? {m,n}?

In [41]: re.findall(r"ab+?",“abbbbbbbb”) Out[41]: [‘ab’]

In [42]: re.findall(r"ab??",“abbbbbbbb”) Out[42]: [‘a’]

正則表示式的分組

使用()為正則表示式建立內部分組(子組),子組為正則表示式的一部分,可以看做一個內部整體。 有子組的正則表示式仍然是整體去匹配內容,子組需要在整體能夠匹配到內容的前提下發揮作用。

子組的作用:

1.作為內部整體可以改變某些元字元的行為。

In [3]: re.search(r"(ab)+\d+",“ababab1234”).group( ) Out[3]: ‘ababab1234’ In [4]: re.search(r"\[email protected]\w+.cn|com",“[email protected]”).group( ) Out[4]: ‘com’ In [5]: re.search(r"\[email protected]\w+.(cn|com)",“[email protected]”).group( ) Out[5]: ‘[email protected]

2.子組在匹配到內容的情況下,可以單獨提取出匹配內容。

In [7]: re.search(r"(https|http|ftp)?/\S+",“https://www.baidu.com”).group(1) Out[7]: ‘https’

子組使用的注意事項:

  1. 一個正則表示式中可以有多個子組
  2. 子組一般由外到內,由左到右稱之為第一,第二,第三…子組
  3. 子組不能重疊或者巢狀過多

捕獲組和非捕獲組

格式: (?P<name>pattern)

In [8]: re.search(r"(?P<dog>ab)cdef",'abcdefghi').group('dog') Out[8]: ‘ab’ #給子組命名dog,利用名字獲取子組內容

正則表示式的設計原則:

  1. 正確性:能正確匹配到目標內容
  2. 排他性:除了要匹配的內容,儘可能不會匹配與到其他內容
  3. 全面型:儘可能對目標字串各自情況進行考慮,做到不遺漏

re模組

regex = compile(pattern, flags = 0)

  • 功能 : 生成正則表示式物件
  • 引數 : pattern 正則表示式     flags 功能標誌位,豐富正則表示式的匹配功能
  • 返回值 : 返回正則表示式物件

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

  • 功能 :從目標字串查詢正則匹配內容
  • 引數 :pattern 正則表示式    string 目標字串    flags 標誌位
  • 返回值 : 返回匹配到的內容(如果正則有子組,則只返回子組對應內容!!)

regex.findall(string, pos, endpos)

  • 功能 :從目標字串查詢所有正則匹配內容
  • 引數 :string 目標字串     pos 擷取目標字串的起始位置     endpos 擷取目標字串的終止位置
  • 返回值 :返回匹配到的內容列表,如果正則有子組則只返回子組中的內容

@import “./code/regex.py”

import re 

pattern = r"(\w+):(\d+)"
s = "zhang:1994 li:1993"

#re直接呼叫
l = re.findall(pattern,s,flags = 0)
print(l)  # [('zhang', '1994'), ('li', '1993')]

#compile物件呼叫
regex = re.compile(pattern,flags = 0)
l = regex.findall(s,pos=0,endpos=12)
print(l)  # [('zhang', '1994')]

re.split(pattern, string, flags)

  • 功能 :從目標字串查詢所有正則匹配內容
  • 引數 :pattern  正則表示式     string  目標字串     flags 標誌位
  • 返回值 :返回匹配到的內容列表,如果正則有子組則只返回子組中的內容

例如:./code/re_split.py

#示意re模組的split的用法
import re

l = re.split(r'\s+','hello world nihao beijing',flags = 0)
print(l)  #['hello', 'world', 'nihao', 'beijing']

re.sub(pattern, replaceStr, string, max, flags)

  • 功能:使用字串替換正則匹配的內容
  • 引數:pattern 正則表示式     replaceStr 替換的字串     string 目標字串     max 最多替換幾處,預設全部替換     flags 標誌位
  • 返回值:返回替換後的字串

例如:./code/re_sub.py

re.subn(pattern, replaceStr, string, max, flags)

  • 功能:使用字串替換正則匹配的內容
  • 引數:pattern:正則表示式    replaceStr:替換的字串    string:目標字串    max:最多替換幾處,預設全部替換    flags 標誌位
  • 返回值:返回替換後的字串 和 替換了幾處

例如:/code/re_sub.py

#示意re模組的sub / sunb的用法
import re

s = re.sub(r'\s+','**','hello world nihao beijing')
print(s)  # hello**world**nihao**beijing

s = re.sub(r'\s+','**','hello world nihao beijing',2)
print(s)  # hello**world**nihao beijing

s = re.subn(r'\s+','**','hello world nihao beijing',2)
print(s)  # ('hello**world**nihao beijing', 2)

re.finditer(pattern, string)

  • 功能: 使用正則表示式匹配目標字串
  • 引數: pattern 正則表示式     string 目標字串
  • 返回值: 返回一個迭代物件,迭代到的內容是一個match物件

fullmatch(pattern,string,flags)

  • 功能: 絕對匹配目標字串
  • 引數: pattern 正則     string 目標字串
  • 返回值:match物件

例:@import “./code/regex1.py”

match(pattern, string, flags)

  • 功能: 從開頭位置匹配目標字串
  • 引數: pattern 正則     string 目標字串     flags
  • 返回值:返回匹配到的match物件,如果沒匹配成功返回None

例:@import “./code/regex1.py”

search(pattern, string, flags)

  • 功能: 正則表示式匹配目標字串,只匹配第一處!!
  • 引數: pattern, string, flags
  • 返回值:返回匹配到的match物件,如果沒匹配成功返回None

例:@import “./code/regex1.py”

import re 

pattern = r'\d+'
s = "2008年事情多,08奧運,512地震"

it = re.finditer(pattern,s) 

# print(dir(next(it)))

for i in it:
    #match物件group函式獲取匹配內容
    print(i.group()) # 2008  08   512

try:
    obj = re.fullmatch(r'\w+','hello1973')
    print(obj.group())  # hello1973
except AttributeError as e:
    print(e)

obj = re.match(r'[A-Z]\w+',"Hello World")
print(obj.group())  # Hello

obj = re.search(r'\d+',s)
print(obj.group())  # 2008

regex 物件屬性:

pattern:
In [9]: regex = re.compile(r'abcdef')
In [10]: regex.pattern
Out[10]: 'abcdef'
flags: 表示標誌位常亮值
group: 表示正則有多少個子組
groupindex: 生成(捕獲組名和對應第幾組)的鍵值對,構成的字典 #

作業:

  1. 熟記正則表示式元字元
  2. 找一個文件,使用正則表示式:
    1. 匹配其中的大寫子母開頭的單詞
    2. 匹配其中所有的數字(整數,浮點數,負數,百分數,分數…)
  3. 複習:regex物件呼叫函式