Python學習:13.Python正則表達式

来源:https://www.cnblogs.com/liudi2017/archive/2018/07/08/9278885.html
-Advertisement-
Play Games

一、正則表達式簡介 正則表達式是一個特殊的字元序列,它能幫助你方便的檢查一個字元串是否與某種模式匹配。 Python 自1.5版本起增加了re 模塊,它提供 Perl 風格的正則表達式模式。 就其本質而言,正則表達式(或 RE)是一種小型的、高度專業化的編程語言, (在Python中)它內嵌在Pyt ...


一、正則表達式簡介

  正則表達式是一個特殊的字元序列,它能幫助你方便的檢查一個字元串是否與某種模式匹配。 Python 自1.5版本起增加了re 模塊,它提供 Perl 風格的正則表達式模式。

  就其本質而言,正則表達式(或 RE)是一種小型的、高度專業化的編程語言, (在Python中)它內嵌在Python中,並通過 re 模塊實現。正則表達式模式被 編譯成一系列的位元組碼,然後由用 C 編寫的匹配引擎執行。

  re 模塊使 Python 語言擁有全部的正則表達式功能。 compile 函數根據一個模式字元串和可選的標誌參數生成一個正則表達式對象。該對象擁有一系列方法用於正則表達式匹配和替換。 re 模塊也提供了與這些方法功能完全一致的函數,這些函數使用一個模式字元串做為它們的第一個參數。

   

二、字元匹配

1.普通字元:大多數字元和字母都會和自身匹配

>>> re.findall("alexsel","gtuanalesxalexselericapp")
['alexsel']
>>> re.findall("alexsel","gtuanalesxalexswxericapp")
[]
>>> re.findall("alexsel","gtuanalesxalexselwupeiqialexsel")
['alexsel', 'alexsel']

2.元字元: .   ^   $   *   +   ?   { }   [ ]   |   ( )  \

  • .   :匹配一個除了換行符任意一個字元    
>>> re.findall("alexsel.w","aaaalexselaw")
['alexselaw']
#一個點只能匹配一個字元
  • ^  :只有後面跟的字元串在開頭,才能匹配上
>>> re.findall("^alexsel","gtuanalesxalexselgeappalexsel")
[]
>>> re.findall("^alexsel","alexselgtuanalesxalexselwgtappqialexsel")
['alexsel']
#"^"這個符號控制開頭,所以寫在開頭
  • $  :只有它前面的字元串在檢測的字元串的最後,才能匹配上
>>> re.findall("alexsel$","alexselseguanalesxalexselganapp")
[]
>>> re.findall("alexsel$","alexselgtaanalesxalexsssiqialexsel")
['alexsel']
  • *  :它控制它前面那個字元,他前面那個字元出現0到多個都可以匹配上
>>> re.findall("alexsel*","aaaalexse")
['alexse']
>>> re.findall("alexsel*","aaaalexsel")
['alexsel']
>>> re.findall("alex*","aaaalexsellllll")
['alexsellllll']    
  • + :匹配前面那個字元1到多次
>>> re.findall("alexsel+","aaaalexselll")
['aleselll']
>>> re.findall("alexsel+","aaaalexsel")
['alexsel']
>>> re.findall("alexsel+","aaaalexse")
[]    
  • ? :匹配前面那個字元0到1個,多餘的只匹配一個
>>> re.findall("alexsel?","aaaalexse")
['ale']
>>> re.findall("alexsel?","aaaalexsel")
['alexsel']
>>> re.findall("alexsel?","aaaalexsellll")
['alexsel']
  • {}  :控制它前面一個字元的匹配個數,可以有區間(閉區間),有區間的情況下按照多的匹配
>>> re.findall("alexsel{3}","aaaalexselllll")
['alexselll']
>>> re.findall("alexsel{3}","aaaalexsell")
[]
>>> re.findall("alexsel{3}","aaaalexse")
[]
>>> re.findall("alexsel{3}","aaaalexselll")
['alexselll']
>>> re.findall("alexsel{3,5}","aaaalexsellllllll")
['alexselllll']
>>> re.findall("alexsel{3,5}","aaaalexselll")
['alexselll']
>>> re.findall("alexsel{3,5}","aaaalexsell")
[]
  • \  :

  後面跟元字元去除特殊功能,
  後面跟普通字元實現特殊功能。
  引用序號對應的字組所匹配的字元串 (一個括弧為一個組)。
  在開頭加上 r 表示不轉義。

#\2 就相當於第二個組(eric)
>>> re.search(r"(alexsel)(eric)com\2","alexselericcomeric").group()
'alexselericcomeric'
>>> re.search(r"(alexsel)(eric)com\1","alexselericcomalex").group()
'alexselericcomalex'
>>> re.search(r"(alexsel)(eric)com\1\2","alexselericcomalexseleric").group()
'alexselericcomalexeric'

  \d  :匹配任何十進位數;它相當於類[0-9]

>>> re.findall("\d","aaazz1111344444c")
['1', '1', '1', '1', '3', '4', '4', '4', '4', '4']
>>> re.findall("\d\d","aaazz1111344444c")
['11', '11', '34', '44', '44']
>>> re.findall("\d0","aaazz1111344444c")
[]
>>> re.findall("\d3","aaazz1111344444c")
['13']
>>> re.findall("\d4","aaazz1111344444c")
['34', '44', '44']

  \D  :匹配任何非數字字元;它相當於類[^0-9]

>>> re.findall("\D","aaazz1111344444c")
['a', 'a', 'a', 'z', 'z', 'c']
>>> re.findall("\D\D","aaazz1111344444c")
['aa', 'az']
>>> re.findall("\D\d\D","aaazz1111344444c")
[]
>>> re.findall("\D\d\D","aaazz1z111344444c")
['z1z']

  \s  :匹配任何空白字元;它相當於類[ \t\n\r\f\v]

>>> re.findall("\s","aazz1 z11..34c")
[' ']

  \S  :匹配任何非空白字元;它相當於類[^ \t\n\r\f\v]

  \w  :匹配任何字母數字字元;他相當於類[a-zA-Z0-9_]

>>> re.findall("\w","aazz1z11..34c")
['a', 'a', 'z', 'z', '1', 'z', '1', '1', '3', '4', 'c']

  \W  :匹配任何非字母數字字元;它相當於類[^a-zA-Z0-9_]

  \b  :匹配一個單詞邊界,也就是指單詞和空格間的位置

>>> re.findall(r"\babc\b","abc sdsadasabcasdsadasdabcasdsa")
['abc']
>>> re.findall(r"\balexsel\b","abc alexsel abcasdsadasdabcasdsa")
['alexsel']
>>> re.findall("\\balexsel\\b","abc alexsel abcasdsadasdabcasdsa")
['alexsel']
>>> re.findall("\balexsel\b","abc alexsel abcasdsadasdabcasdsa")
[]

   ()  :把括弧內字元作為一個整體去處理

>>> re.search(r"a(\d+)","a222bz1144c").group()
'a222'
>>> re.findall("(ab)*","aabz1144c")
['', 'ab', '', '', '', '', '', '', '']  #將括弧里的字元串作為整和後面字元逐個進行匹配,在這裡就首先將後面字元串里的a和ab進
#行匹配,開頭匹配成功,在看看後面是a,和ab中的第二個不匹配,然後就看後面字元串中的第二個a,和ab匹配,首先a匹配成功,b也匹配成功,拿到匹配
#然後在看後面字元串中的第三個是b,開頭匹配失敗,到第四個,後面依次
>>> re.search(r"a(\d+)","a222bz1144c").group()
'a222'
>>> re.search(r"a(\d+?)","a222bz1144c").group() +的最小次數為1
'a2'
>>> re.search(r"a(\d*?)","a222bz1144c").group() *的最小次數為0
'a'

#非貪婪匹配模式 加? ,但是如果後面還有匹配字元,就無法實現非貪婪匹配 #(如果前後均有匹配條件,則無法實現非貪婪模式) >>> re.findall(r"a(\d+?)b","aa2017666bz1144c") ['2017666'] >>> re.search(r"a(\d*?)b","a222bz1144c").group() 'a222b' >>> re.search(r"a(\d+?)b","a277722bz1144c").group() 'a277722b'

 

 元字元在字元集里就代表字元,沒有特殊意義(有幾個例外)

>>> re.findall("a[.]d","aaaacd")
[]
>>> re.findall("a[.]d","aaaa.d")
['a.d']

例外
[-] [^] [\]

[-]

#匹配單個字元,a到z所有的字元
>>> re.findall("[a-z]","aaaa.d")
['a', 'a', 'a', 'a', 'd']
>>> re.findall("[a-z]","aaazzzzzaaccc")
['a', 'a', 'a', 'z', 'z', 'z', 'z', 'z', 'a', 'a', 'c', 'c', 'c']
>>>
>>> re.findall("[1-3]","aaazz1111344444c")
['1', '1', '1', '1', '3']

[^]

#匹配除了這個範圍里的字元,(^在這裡有 非 的意思)
>>> re.findall("[^1-3]","aaazz1111344444c")
['a', 'a', 'a', 'z', 'z', '4', '4', '4', '4', '4', 'c']
>>> re.findall("[^1-4]","aaazz1111344444c")
['a', 'a', 'a', 'z', 'z', 'c']

[\]

>>> re.findall("[\d]","aazz1144c")
['1', '1', '4', '4']

 

  我們首先考察的元字元是"[" 和 "]"。它們常用來指定一個字元類別,所謂字元類 別就是你想匹配的一個字元集。字元可以單個列出,也可以用“-”號分隔的兩個給定 字元來表示一個字元區間。例如,[abc] 將匹配"a", "b", 或 "c"中的任意一個字 符;也可以用區間[a-c]來表示同一字元集,和前者效果一致。如果你只想匹配小寫 字母,那麼 RE 應寫成 [a-z],元字元在類別里並不起作用。例如,[akm$]將匹配字元"a", "k", "m", 或 "$" 中 的任意一個;"$"通常用作元字元,但在字元類別里,其特性被除去,恢覆成普通字元。

 

三、Python正則表達式各種函數以及參數解析

 

match: re.match(pattern,string,flags=0)

flags 編譯標誌位,用於修改正則表達式的匹配方式,如:是否區別大小寫

re.match("com","comwww.runcomoob").group()
'com' re.match(
"com","Comwww.runComoob",re.I).group()
'Com'

flags 編譯標誌位

re.I 使匹配對大小寫不敏感

>>> re.search("com","COM",re.I).group()
    'COM'

re.L 做本地化識別(locale-aware)匹配

re.M 多行匹配,影響^和$

re.S 使.匹配包括換行在內的所有字元

>>> re.findall(".","abc\nde")
['a', 'b', 'c', 'd', 'e']
>>> re.findall(".","abc\nde",re.S)
['a', 'b', 'c', '\n', 'd', 'e']

re.U 根據Unicode字元集解析字元。這個標誌影響 \w, \W, \b, \B

re.X 該標誌通過給予你更靈活的格式以便你將正則表達式寫得更易於理解。

 

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

re.search("\dcom","www.4comrunoob.5com").group()
'4com'

 

re.match與re.search的區別

  re.match只匹配字元串的開始,如果字元串開始不符合正則表達式,則匹配失敗,函數返回None;而re.search匹配整個字元串,直到找到一個匹配。

  match和search一旦匹配成功,就是一個match object對象,而match object對象有以下方法:

  • group()    返回被RE匹配的字元串
  • start()       返回匹配開始的位置
  • end()        返回匹配結束的位置
  • span()      返回一個元組包含匹配(開始,結束)的位置
  • group()    返回re整體匹配的字元串,可以一次輸入多個組號,對應組號匹配的字元串,獲取匹配到的所有結果(無論是否有組)
  • a. group ()  返回re整體匹配的字元串,
  • b. group (n,m)    返回組號為n,m所匹配的字元串,如果組號不存在,則返回indexError異常
  • c. groups()   groups() 方法返回一個包含正則表達式中所有小組字元串的元組,從 1 到所含的小組號,通常groups()不需要參數,返回一個元組,元組中的元就是正則表達式中定義的組。
a = "123abc456"
re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(0)   #123abc456,返回整體
re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(1)   #123
re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(2)   #abc
re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(3)   #456

 

在上面的代碼練習中,我們看到很多代碼後面加有group,在這我們就針對這個group進行解析。

m = re.match("([abc])+", "abc")

  一般,m.group(N) 返回第N組括弧匹配的字元。 而m.group() == m.group(0) == 所有匹配的字元,與括弧無關,這個是API規定的。 m.groups() 返回所有括弧匹配的字元,以tuple格式。m.groups() == (m.group(0), m.group(1), ...)

 

sub subn:

re.sub(pattern, repl, string, max=0)

>>> re.sub("g.t","have","I get A, I got B, I gut C")#匹配g.t字元,用have替換(.匹配一個除了換行符任意一個字元)
'I have A, I have B, I have C'
>>> re.sub("got","have","I get A, I got B, I gut C")
'I get A, I have B, I gut C'
>>> re.sub("g.t","have","I get A, I got B, I gut C",2)#替換兩個
'I have A, I have B, I gut C'
>>> re.sub("g.t","have","I get A, I got B, I gut C",1)
'I have A, I got B, I gut C'
>>> re.subn("g.t","have","I get A, I got B, I gut C")#使用re.subn顯示替換里多少個
('I have A, I have B, I have C', 3)

 

re.compile(strPattern[, flag]):

  這個方法是Pattern類的工廠方法,用於將字元串形式的正則表達式編譯為Pattern對象。

  第二個參數flag是 匹配模式,取值可以使用按位或運算符‘|‘表示同時生效,比如re.I | re.M可以把正則表達式編譯成一個正則表達式對象。可以把那些經常使用的正則表達式編譯成正則表達式對象,這樣可以提高一定的效率。

  一個正則表達式對象的一個例子:

>>> text = "JGood is a handsome boy, he is cool, clever, and so on..."
>>> regex = re.compile(r"\w*oo\w*")
>>> print regex.findall(text)
['JGood', 'cool']

 

split:

p = re.compile(r"\d+")       #+:匹配前面那個字元1到多次
p.split("one1two2three3four4")        #spilt分割

>>> p = re.compile(r"\d+")
>>> p.split("one1two2three3four4")
['one', 'two', 'three', 'four', '']

re.split("\d+","one1two2three3four4")

>>> re.split("\d+","one1two2three3four4")
['one', 'two', 'three', 'four', '']

>>> re.split("\d+","4one1two2three3four4")
['', 'one', 'two', 'three', 'four', '']#如果分割時左邊或者右邊已經被分過
>>> re.split("[bc]","abcd")#或者是無字元的情況下,就分出一個空字元
['a', '', 'd']

 

finditer():

>>> p = re.compile(r"\d+")
>>> iterator = p.finditer("12 drumm44ers drumming, 11 ... 10 ...")
>>>
>>> iterator
<callable-iterator object at 0x02626990>
>>> for match in iterator:
...      match.group() , match.span()#每個數字以及它們出現的位置
...
('12', (0, 2))
('44', (8, 10))
('11', (24, 26))
('10', (31, 33))

 

由於我們是在python下使用的正則表達式,所以特殊字元需要多次轉意,而使用了rawstring之後,就不用在多次轉意僅僅就使用正則的規則就可以。

>>> re.findall(r"\d","www4dd6")
['4', '6']
>>> re.findall("\\d","www4dd6")
['4', '6']
>>> re.findall("\d","www4dd6")
['4', '6']
#在這裡\d成功的原因是因為\d在ascii碼中沒有特殊含義,所以在這裡就自動轉意了,不過正規的寫法就是前兩個

 

單詞邊界

>>> re.findall(r"\babc","abcsd abc")
['abc', 'abc']
>>> re.findall(r"abc\b","abcsd abc")
['abc']
>>> re.findall(r"abc\b","abcsd abc*")
['abc']
>>> re.findall(r"\babc","*abcsd*abc")
['abc', 'abc']
#檢測單詞邊界不一定就是空格,還可以是除了字母以外的特殊字元

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 網站首頁導航 ...
  • 基於React的一個簡單Todo-list 先賭為快:線上DEMO,感覺還不錯點一下star -_- ~ 源碼地址: 一、已經完成的功能 1、新增選項(預設未完成) 2、完成狀態可以切換 3、當前選項可以刪除 4、全部選項選中狀態切換 5、全部個數,完成個數,未完成個數實時讀取 6、刷新狀態不變 7 ...
  • 1. 使用Set ES6 提供了新的數據結構Set, 它類似數組,和C++中的set容器一樣,它成員的值都是唯一的,沒有重覆的值;Set本身是一個構造函數,用來生成Set數據結構。 還有更簡單的方式 上面這種方式在於Array.from方法可以將Set結構轉化為數組。如果你還覺得不過癮,那麼還有一種 ...
  • HTML5 標準事件 oninput 和 IE 專屬事件 onpropertychange 事件實時監聽input輸入框value的變化 ...
  • 本篇文章主要介紹設計模式中的單例模式使用。有經典餓漢式和飽漢式,也包含最優的單例模式的介紹使用。 ...
  • Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3121 Accepted Submission(s): 778 Problem Descript ...
  • Description Input 第1行包含5個整數,依次為 x_0,a,b,c,d ,描述小H採用的隨機數生成演算法所需的隨機種子。第2行包含三個整數 N,M,Q ,表示小H希望生成一個1到 N×M 的排列來填入她 N 行 M 列的棋盤,並且小H在初始的 N×M 次交換操作後,又進行了 Q 次額外 ...
  • Flask中的session cookie:是一種保存數據的格式,也可以看成是保存數據的一個“盒子”,伺服器返回cookie給瀏覽器(由伺服器產生),由瀏覽器保存在本地,下次再訪問此伺服器時瀏覽器就會自動將此cookie一起發送給伺服器。 session:也是一種保存數據的格式,也可以看成是保存數據 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...