Python正則進階

来源:https://www.cnblogs.com/smiler/archive/2018/07/25/9364022.html
-Advertisement-
Play Games

[TOC] 1.Python正則表達式模塊 1.1 正則表達式處理字元串主要有四大功能 1. 匹配 查看一個字元串是否符合正則表達式的語法,一般返回true或者false 2. 獲取 正則表達式來提取字元串中符合要求的文本 3. 替換 查找字元串中符合正則表達式的文本,並用相應的字元串替換 4. 分 ...


目錄

1.Python正則表達式模塊

1.1 正則表達式處理字元串主要有四大功能

  1. 匹配 查看一個字元串是否符合正則表達式的語法,一般返回true或者false
  2. 獲取 正則表達式來提取字元串中符合要求的文本
  3. 替換 查找字元串中符合正則表達式的文本,並用相應的字元串替換
  4. 分割 使用正則表達式對字元串進行分割。

1.2 Python中re模塊使用正則表達式的兩種方法

  1. 使用re.compile(r,f)方法生成正則表達式對象,然後調用正則表達式對象的相應方法。這種做法的好處是生成正則對象之後可以多次使用。
  2. re模塊中對正則表達式對象的每個對象方法都有一個對應的模塊方法,唯一不同的是傳入的第一個參數是正則表達式字元串。此種方法適合於只使用一次的正則表達式。

1.3 正則表達式對象的常用方法

1. rx.findall(s,start, end):

  返回一個列表,如果正則表達式中沒有分組,則列表中包含的是所有匹配的內容,如果正則表達式中有分組,則列表中的每個元素是一個元組,元組中包含子分組中匹配到的內容,但是沒有返回整個正則表達式匹配的內容

2. rx.finditer(s, start, end):

  返回一個可迭代對象
  對可迭代對象進行迭代,每一次返回一個匹配對象,可以調用匹配對象的group()方法查看指定組匹配到的內容,0表示整個正則表達式匹配到的內容

3. rx.search(s, start, end):

  返回一個匹配對象,倘若沒匹配到,就返回None
  search方法只匹配一次就停止,不會繼續往後匹配

4. rx.match(s, start, end):

   如果正則表達式在字元串的起始處匹配,就返回一個匹配對象,否則返回None

5. rx.sub(x, s, m):

  返回一個字元串。每一個匹配的地方用x進行替換,返回替換後的字元串,如果指定m,則最多替換m次。對於x可以使用/i或者/g

6. rx.subn(x, s, m):

   與re.sub()方法相同,區別在於返回的是二元組,其中一項是結果字元串,一項是做替換的個數。

7. rx.split(s, m):

 分割字元串,返回一個列表,用正則表達式匹配到的內容對字元串進行分割

      如果正則表達式中存在分組,則把分組匹配到的內容放在列表中每兩個分割的中間作為列表的一部分,如:

  rx = re.compile(r"(\d)[a-z]+(\d)")
  s = "ab12dk3klj8jk9jks5"
  result = rx.split(s)

返回['ab1', '2', '3', 'klj', '8', '9', 'jks5']

8. rx.flags():正則表達式編譯時設置的標誌

9. rx.pattern():正則表達式編譯時使用的字元串

1.4 匹配對象的屬性與方法

01. m.group(g, ...)

  返回編號或者組名匹配到的內容,預設或者0表示整個表達式匹配到的內容,如果指定多個,就返回一個元組

02. m.groupdict(default)

   返回一個字典。字典的鍵是所有命名的組的組名,值為命名組捕獲到的內容
   如果有default參數,則將其作為那些沒有參與匹配的組的預設值。

03. m.groups(default)

      返回一個元組。包含所有捕獲到內容的子分組,從1開始,如果指定了default值,則這個值作為那些沒有捕獲到內容的組的值

04. m.lastgroup()

      匹配到內容的編號最高的捕獲組的名稱,如果沒有或者沒有使用名稱則返回None(不常用)

05. m.lastindex()

      匹配到內容的編號最高的捕獲組的編號,如果沒有就返回None。

06. m.start(g):

      當前匹配對象的子分組是從字元串的那個位置開始匹配的,如果當前組沒有參與匹配就返回-1

07. m.end(g)

      當前匹配對象的子分組是從字元串的那個位置匹配結束的,如果當前組沒有參與匹配就返回-1

08. m.span()

      返回一個二元組,內容分別是m.start(g)和m.end(g)的返回值

09. m.re()

      產生這一匹配對象的正則表達式

10. m.string()

      傳遞給match或者search用於匹配的字元串

11. m.pos()

      搜索的起始位置。即字元串的開頭,或者start指定的位置(不常用)

12. m.endpos()

      搜索的結束位置。即字元串的末尾位置,或者end指定的位置(不常用)

1.5 總結

  1. 對於正則表達式的匹配功能,Python沒有返回true和false的方法,但可以通過對match或者search方法的返回值是否是None來判斷
  2. 對於正則表達式的搜索功能,如果只搜索一次可以使用search或者match方法返回的匹配對象得到,對於搜索多次可以使用finditer方法返回的可迭代對象來迭代訪問
  3. 對於正則表達式的替換功能,可以使用正則表達式對象的sub或者subn方法來實現,也可以通過re模塊方法sub或者subn來實現,區別在於模塊的sub方法的替換文本可以使用一個函數來生成
  4. 對於正則表達式的分割功能,可以使用正則表達式對象的split方法,需要註意如果正則表達式對象有分組的話,分組捕獲的內容也會放到返回的列表中

2 正則匹配與替換

1.python里使用正則表達式的組匹配自引用

在前面學習過組的匹配,也就是一個括弧包含就叫做一個組。在一個複雜一點的正則表達式里,比如像(1)(2)(3)這樣,就匹配三組,如果想在這個表達式里引用前面匹配的組,怎麼辦呢?其實最簡單的方式是通過組號來引用,比如像(1)(2)(3)——\1。使用“\num”的語法來自引用,如下例子:

#python 3.6
#
import re
 
address = re.compile(
    r'''
    # The regular name
    (\w+)               # first name
    \s+
    (([\w.]+)\s+)?      # optional middle name or initial
    (\w+)               # last name
    \s+
    <
    # The address: [email protected]
    (?P<email>
      \1               # first name
      \.
      \4               # last name
      @
      ([\w\d.]+\.)+    # domain name prefix
      (com|org|edu)    # limit the allowed top-level domains
    )
    >
    ''',
    re.VERBOSE | re.IGNORECASE)
 
candidates = [
    u'First Last <[email protected]>',
    u'Different Name <[email protected]>',
    u'First Middle Last <[email protected]>',
    u'First M. Last <[email protected]>',
]
 
for candidate in candidates:
    print('Candidate:', candidate)
    match = address.search(candidate)
    if match:
        print('  Match name :', match.group(1), match.group(4))
        print('  Match email:', match.group(5))
    else:
        print('  No match')

結果輸出如下:

Candidate: First Last <[email protected]>
  Match name : First Last
  Match email: [email protected]
Candidate: Different Name <[email protected]>
  No match
Candidate: First Middle Last <[email protected]>
  Match name : First Last
  Match email: [email protected]
Candidate: First M. Last <[email protected]>
  Match name : First Last
  Match email: [email protected]

在這個例子里,就引用了第1組first name和第4組last name的值,實現了前後不一致的EMAIL的姓名,就丟掉它。

2.python里使用正則表達式的組匹配通過名稱自引用

在前學習過正則表達式的組可以通過組號來自引用,看起來使用很簡單的樣子,其實它還是不容易維護的,比如你某一天需要在這個正則表達式里插入一個組時,就發現後面的組號全打亂了,因此需要一個一個地更改組號,有沒有更容易維護的方式呢?是有的,就是使用組名稱來引用。如下麵的例子:

#python 3.6

#
import re
 
address = re.compile(
    '''
    # The regular name
    (?P<first_name>\w+)
    \s+
    (([\w.]+)\s+)?      # optional middle name or initial
    (?P<last_name>\w+)
    \s+
    <
    # The address: [email protected]
    (?P<email>
      (?P=first_name)
      \.
      (?P=last_name)
      @
      ([\w\d.]+\.)+    # domain name prefix
      (com|org|edu)    # limit the allowed top-level domains
    )
    >
    ''',
    re.VERBOSE | re.IGNORECASE)
 
candidates = [
    u'cai junsheng <[email protected]>',
    u'Different Name <[email protected]>',
    u'Cai Middle junsheng <[email protected]>',
    u'Cai M. junsheng <[email protected]>',
]
 
for candidate in candidates:
    print('Candidate:', candidate)
    match = address.search(candidate)
    if match:
        print('  Match name :', match.groupdict()['first_name'],
              end=' ')
        print(match.groupdict()['last_name'])
        print('  Match email:', match.groupdict()['email'])
    else:
        print('  No match')

結果輸出如下:

Candidate: cai junsheng <[email protected]>
  Match name : cai junsheng
  Match email: [email protected]
Candidate: Different Name <[email protected]>
  No match
Candidate: Cai Middle junsheng <[email protected]>
  Match name : Cai junsheng
  Match email: [email protected]
Candidate: Cai M. junsheng <[email protected]>
  Match name : Cai junsheng
  Match email: [email protected]

在這個例子里,就是通過(?P=first_name)引用。

3.python里使用正則表達式的組匹配是否成功之後再自引用

在前面學習了通過名稱或組號來引用本身正則表達式里的組內容,可以實現前後關聯式的相等判斷。如果再更進一步,比如當前面組匹配成功之後,就選擇一種模式來識別,而不匹配成功又選擇另外一種模式進行識別,這相當於if...else...語句的選擇。我們來學習這種新的語法:(?(id)yes-expression|no-expression)。其中id是表示組名稱或組編號, yes-expression是當組匹配成功之後選擇的正則表達式,而no-expression 是不匹配成功之後選擇的正則表達式。如下例子:

#python 3.6
#
import re
 
address = re.compile(
    '''
    ^
    # A name is made up of letters, and may include "."
    # for title abbreviations and middle initials.
    (?P<name>
       ([\w.]+\s+)*[\w.]+
     )?
    \s*
    # Email addresses are wrapped in angle brackets, but
    # only if a name is found.
    (?(name)
      # remainder wrapped in angle brackets because
      # there is a name
      (?P<brackets>(?=(<.*>$)))
      |
      # remainder does not include angle brackets without name
      (?=([^<].*[^>]$))
     )
    # Look for a bracket only if the look-ahead assertion
    # found both of them.
    (?(brackets)<|\s*)
    # The address itself: [email protected]
    (?P<email>
      [\w\d.+-]+       # username
      @
      ([\w\d.]+\.)+    # domain name prefix
      (com|org|edu)    # limit the allowed top-level domains
     )
    # Look for a bracket only if the look-ahead assertion
    # found both of them.
    (?(brackets)>|\s*)
    $
    ''',
    re.VERBOSE)
 
candidates = [
    u'Cai junsheng <[email protected]>',
    u'No Brackets [email protected]',
    u'Open Bracket <[email protected]',
    u'Close Bracket [email protected]>',
    u'[email protected]',
]
 
for candidate in candidates:
    print('Candidate:', candidate)
    match = address.search(candidate)
    if match:
        print('  Match name :', match.groupdict()['name'])
        print('  Match email:', match.groupdict()['email'])
    else:
        print('  No match')

結果輸出如下:

Candidate: Cai junsheng <[email protected]>
  Match name : Cai junsheng
  Match email: [email protected]
Candidate: No Brackets [email protected]
  No match
Candidate: Open Bracket <[email protected]
  No match
Candidate: Close Bracket [email protected]>
  No match
Candidate: [email protected]
  Match name : None
  Match email: [email protected]

在這裡,當name組出現時才會尋找括弧< >,如果括弧不成對就不匹配成功;如果name組不出現,就不需要括弧,因此選擇了另一個正則表達式。

4.python里使用正則表達式來替換匹配成功的組

在前面主要學習了怎麼樣匹配成功,都沒有修改原來的內容的。現在來學習一個匹配成功之後修改相應的內容,在這裡使用sub()函數來實現這個功能,同時使用引用組號來插入原來的字元,例子如下:

#python 3.6
#
import re
 
bold = re.compile(r'\*{2}(.*?)\*{2}')
 
text = 'Make this **cai**.  This **junsheng**.'
 
print('Text:', text)
print('Bold:', bold.sub(r'<b>\1</b>', text))

結果輸出如下:

Text: Make this **cai**.  This **junsheng**.
Bold: Make this <b>cai</b>.  This <b>junsheng</b>.

5.python里使用正則表達式來替換匹配成功的組名

在前面學習了找到組之後,通過組序號來替換,比如像bold.sub(r'\1', text)),這裡是通過\1來替換的,這樣的方式就是簡單,快捷。但是不方便維護,不方便記憶,要想把這點改進一下,就得使用組名稱的方式來替換,就跟前面學習組名稱匹配一樣,給一個組起一個名稱,也像為什麼給每一個人起一個名稱一樣,方便區分和記憶。因此使用這樣的語法:\g

#python 3.6
#
import re
 
bold = re.compile(r'\*{2}(?P<bold_text>.*?)\*{2}')
 
text = 'Make this **cai**.  This **junsheng**.'
 
print('Text:', text)
print('Bold:', bold.sub(r'<b>\g<bold_text></b>', text))

結果輸出如下:

Text: Make this **cai**.  This **junsheng**.
Bold: Make this <b>cai</b>.  This <b>junsheng</b>.

6.python里使用正則表達式來替換匹配成功的組並限定替換的次數

在前面學習過通過組名稱來替換原來的字元串,這種替換隻要出現相同的匹配成功,就會替換,而不管出現多少次。如果有一天,項目經理說要只需要替換第一個,或者前5個,怎麼辦呢?哈哈,這時你就得使用sub函數的count參數了,它可以指定替換的次數,輕鬆地解決了問題,例子如下:

#python 3.6 
#
import re
 
bold = re.compile(r'\*{2}(?P<bold_text>.*?)\*{2}')
 
text = 'Make this **cai**.  This **junsheng**.'
 
print('Text:', text)
print('Bold:', bold.sub(r'<b>\g<bold_text></b>', text, count=1))

結果輸出如下:

Text: Make this **cai**.  This **junsheng**.
Bold: Make this <b>cai</b>.  This **junsheng**.

7.python里使用正則表達式來替換匹配成功的組並輸出替換的次數

在前面我們學習過怎麼樣限制替換的次數,如果我們想知道正則表達式里匹配成功之後,替換字元串的次數,那麼需要怎麼辦呢?這是一個好問題,這時就需要採用另一個外函數subn()了。這個函數不但輸出替換後的內容,還輸出替換的次數,例子:

#python 3.6
#
import re
 
bold = re.compile(r'\*{2}(?P<bold_text>.*?)\*{2}')
 
text = 'Make this **cai**.  This **junsheng**.'
 
print('Text:', text)
print('Bold:', bold.subn(r'<b>\g<bold_text></b>', text))

結果輸出如下:

Text: Make this **cai**.  This **junsheng**.
Bold: ('Make this <b>cai</b>.  This <b>junsheng</b>.', 2)

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

-Advertisement-
Play Games
更多相關文章
  • 在簡單工廠模式中產品的創建統一在工廠類的靜態工廠方法中創建,體現了面形對象的封裝性,客戶程式不需要知道產品產生的細節,也體現了面向對象的單一職責原則(SRP),這樣在產品很少的情況下使用起來還是很方便, 但是如果產品很多,並且不斷的有新產品加入,那麼就會導致靜態工廠方法變得極不穩定,每次加入一個新產 ...
  • guava是google的一個開源java框架,其github地址是 https://github.com/google/guava。guava工程包含了若幹被Google的 Java項目廣泛依賴的核心庫,例如:集合 [collections] 、緩存 [caching] 、原生類型支持 [prim ...
  • 主要使用三種集成環境進行安裝,小主們可以自行選擇: ...
  • 一、xxxxxx獲取指定任務爬取的所有url的介面 介面名稱:xxxxxx獲取指定任務爬取的所有url的介面 訪問鏈接: http://IP:PORT/crwalTask/findUrlExceptionById?ctId=ctIdVal&time=timeVal&limit=limitVal 傳入 ...
  • 頁面代碼: <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePat ...
  • 改進版 BFS cpp include using namespace std; define coordi(x,y) ( m (x 1)+y ) const int maxn = 30; const int dx[] = {0,0,1, 1}; const int dy[] = {1, 1,0,0 ...
  • eclipse中: 1.單擊整個項目 run as - maven clean - maven install 2.找到項目所在的路徑 找到所有的jar包 3.把jar包放到linux對應的文件夾 linux中部署項目:1.查看jar是否在運行中 ps -ef | grep SpliderWeb-0 ...
  • Pygame介紹: Pygame是跨平臺Python模塊,專為電子游戲設計,包含圖像、聲音。Pygame是跨平臺Python模塊,專為電子游戲設計,包含圖像、聲音。建立在SDL基礎上,允許實時電子游戲研發而無需被低級語言(如機器語言和彙編語言)束縛。 安裝過程: 1、環境準備:1、安裝python環 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...