Python3正則表達式_re模塊_教程詳解_筆記_完整內容

来源:https://www.cnblogs.com/hikali/archive/2022/05/27/16318948.html
-Advertisement-
Play Games

1.github上上傳項目(略) 2.在sonatype上註冊賬號 https://issues.sonatype.org/secure/Dashboard.jspa 註意記住用戶名和密碼 3.在sonatype創建問題 4.新建完後客服會給提示 主要是要求:groupId要合理,需要按照要求在gi ...


正則表達式,用於在一大堆數據中查找信息,學習後有利於爬蟲信息抓取。

 

“. ^ $ * + ? { } [ ] \ | ( )”是元字元(關鍵字),如要匹配原字元則需加“\”,如“\[”“\\”。為避免與轉義符(\n、\b)衝突,可在字元串前加r,即 r"" 或 r'' 。

 

字元
“\d”表示數字
“\D”表示非數字的字元
“\s”表示空白字元,相當於[ \t\n\r\f\v]
“\S”相當於[^ \t\n\r\f\v]
“\w”表示數字或字母
“\W”表示非數字和字母的字元
“.”表示除換行符'\n'外的所有字元,DOTALL模式下可匹配任何字元(包括'\n')
“[]”整體為一個字元,其中的內容表示"或者"關係,同時元字元全部失效。如:[12]表示'1'或'2',[a-z]表示小寫字母(包括擴展拉丁字母如 'é'),[A-Za-z]表示所有字母,而[^a]表示除'a'以外的所有字元,[a^]表示'a'或'^'。由於元字元失效,從而可以 '[\n]' 的方式表示回車符等轉義符,但複雜情況下仍推薦使用 r""。

 

 

以下字元都不代表實際字元,即所謂零寬度,稱為斷言
“^”指示行的開頭,不代表實際字元,如MULTILINE模式下以“^a”去匹配“b\nab”則span=(2, 3)。若不是MULTILINE,則僅指示字元串開頭。
“$”指示行的末尾。同樣需要MULTILINE
“\A”指示字元串的開頭
“\Z”指示字元串的末尾
“\b”指示詞邊界,即每個單詞的開頭和結尾,單詞結構中可包括數字和字母,其他字元如空格逗號可以將其分割為一個個單詞。可以指示字元串開頭。可能與退格符'\b'衝突,加r或使用'\\b'。
“|”表示或者,優先順序比普通字元還低,如“phone|tele”表示"phone"或"tele"
而“()”可控制“|”的範圍,如“the (phone|tele)”

 

 

 

重覆
“*”表示前一個字元重覆0~+inf次
“+”表示前一個字元重覆1~+inf次
“?”表示前一個字元重覆0或1次,可有可無
“{m}”表示前一個字元重覆m次。
“{a,b}”表示前一個字元重覆a~b次,同時“{,b}”表示0~b,“{a,}”表示a~+inf次。註意大括弧中不可包含空格,如“{a, b}”是錯誤的,應為“{a,b}”。

以上符號預設均為貪婪模式,即匹配儘可能多的字元。如果需匹配儘可能少的字元,可在其後加上“?”符號,如“a*?”為非貪婪模式。

“()”可使重覆符號作用於其括住的全部字元上,如“(br)*”指'br'重覆0~+inf次

 

 


re模塊
基本方法:
“p = re.compile(r'ab*')”編譯一個匹配器(正則),r'ab*'為匹配規則的表達式(模式)

“m = p.match('abbcabd')”在'abbcabd'中從第一個字元開始匹配,結果保存在match對象中並返回
“m = p.search('abbcabd')”在'abbcabd'中不斷向後查找,只返回第一個最先匹配到的內容
“listAll = p.findall('abbcabd')”在'abbcabd'中不斷向後查找所有能匹配的內容,並將其以列表的方式返回
“iterAll = p.finditer('abbcabd')”上一種方式的迭代器版本,迭代時才查找並返回內容

“s = m.group()”或“s = m.group(0)”獲得匹配的內容
“s = m.start()”獲得匹配內容在字元串中的起始索引值,指向匹配內容的第一個字元
“s = m.end()”獲得匹配內容在字元串中的終止索引值,指向匹配內容最後一個字元的後一個字元
“s = m.span()”獲得匹配內容在字元串中的範圍,元組方式返回,範圍為左包含而右不包含的
“print(m)”輸出匹配的範圍和內容

 

 

分組
在正則表達式中把需要的信息用小括弧“()”括起來,即可獲得它們,稱為分組。如:
“p = re.compile(r'\w(\w)(\w+)')”
“m = p.match('This is Python')”
之後“m.group(1)”可返回第一個分組的內容,即'h'
“m.group(2)”可返回第二個分組的內容,即'is'
以此類推
而“m.group()”或“m.group(0)”依然返回匹配到的所有內容,即 'This'
“m.groups()”可將所有分組內容以元組的方式返回,即('h', 'is')

分組編號從左到右,由內而外。如以r'\w((\w)\w+)'匹配'This is Python'則第一個分組內容為 'his',第二個為 'h',groups()得 ('his', 'h')。
“\1”可指代前面第一個分組匹配到的內容,表示“\1”這裡必須要再次出現此內容,可用於檢測雙字(疊詞)。如:

p = re.compile(r'\b(\w+)\s+\1\b')
print(p.search('Paris in the the spring').group())


得:'the the'。

 

註意:分組後“findall”和“finditer”只返回分組的內容,若有多個分組則將每次匹配到的各分組內容以元組的方式存儲在列表中。

 

 

 

更多分組
“(?: ... )”中 ' ... ' 處輸入的表達式匹配後不會被groups()捕獲。可用於不重要信息的重覆如 r'(?:the\s?)*'。稱為非捕獲組
“(?P<gr>...)”可將此分組命名為 'gr' ,之後通過“group('gr')”可獲得此分組的內容。稱為命名組
同時“(?P=gr)”可指代前面分組名為 'gr' 匹配到的內容,表示“(?P=gr)”這裡必須要再次出現此內容。
以上兩種表達式的“P”指Python特有。
“m.groupdict()”可返回所有被命名的分組內容,分組名為鍵(key),分組內容為值(value)
“(?#…)”為註釋,可被忽略
“(?(id/name)a|b)”指如果編號為 'id' 的分組或名稱為 'name' 的命名組存在,則匹配a表達式,否則匹配b表達式

 


前向斷言
“(?=…)”指此處應出現表達式 '...' 所描述的內容,如無則此次匹配失敗。匹配成功後,其自身不計入匹配內容,原因是其自身不代表實際字元,即零寬度。這被稱為前向肯定斷言。如字元串 "What's that?",若以 r"What's(?=\sth)" 匹配之則得 "What's",若以 r"What's(?=\sth)\s\w+[?]$" 匹配之則得 "What's that?"。

“(?!…)”與上一種相反,指此處不應出現表達式 '...' 所描述的內容,如出現則此次匹配失敗。這被稱為前向否定斷言。可用於排除某種文件尾碼,如 r'.*[.](?!bat$)[^.]*$' 只可匹配尾碼為"bat"

 

 

後向斷言
“(?<=…)”為後向肯定斷言,與 '(?=...)' 作用基本相同,不計入匹配內容,但其自身可以代表實際字元。如字元串 "It's spam-egg",若以 r"(?<=-)\w+" search之則仍得 "egg"。“(?<=…)”中不可添加重覆(\s*、a{1, 4}),但可添加其他內容如 '|'

“(?<!…)”為後向否定斷言,與上一種相反,同樣不可添加重覆

 


標誌
可以在re.compile()中增加匹配標誌的參數,相當於對匹配方式進行設置。標誌可以疊加,在其之間需加上 '|' 按位與運算符,如:“p.compile(r'ab*, re.M|re.I)”

“re.M”設置MULTILINE模式(多行匹配模式),使 '^' 指示行的開頭, '$' 指示行的末尾。也可寫為“re.MULTILINE”
“re.I”設置IGNORECASE模式,忽略大小寫,即大寫既可匹配大寫也可匹配小寫,小寫既可匹配小寫也可匹配大寫。也可寫為“re.IGNORECASE”
“re.L”設置LOCALE模式,方便處理本地所使用的拉丁語言。比如 'é' 'ñ' 'ç' 對於西班牙語而言只有 'é' 'ñ' 是字母,但對於法語而言則只有 'é' 'ç' 是字母。未設置re.L時,Python3預設進行 Unicode 匹配,即將 'é' 'ñ' 'ç' 都識別為字母。設置後,則據地區而定。主要影響 '\w' '\W' '\b' '\B' 和大小寫忽略(re.I)。也可寫為“re.LOCALE”
“re.S”設置DOTALL模式,使 '.' 可匹配任何字元,包括 '\n'。也可寫為“re.DOTALL”
“re.A”設置ASCII模式,使預設的 Unicode 匹配變為 ASCII 匹配,影響 '\w' '\W' '\b' '\B' '\s' '\S' 的工作。也可寫為“re.ASCI”
“re.U”設置UNICODE模式,與上一個模式相反,也可寫為“re.UNICODE”
“re.X”設置VERBOSE模式,可使正則表達式更易讀。設置re.X後,表達式中所有空格都將被忽略,並且允許加入註釋,指示各部分的含義,也可寫為“re.VERBOSE”,如:

1 charref = re.compile(r"""
2  &[#]                # Start of a numeric entity reference
3  (
4      0[0-7]+         # Octal form
5    | [0-9]+          # Decimal form
6    | x[0-9a-fA-F]+   # Hexadecimal form
7  )
8  ;                   # Trailing semicolon
9 """, re.VERBOSE)

若未設置re.X則寫為:

1 charref = re.compile("&#(0[0-7]+"
2                      "|[0-9]+"
3                      "|x[0-9a-fA-F]+);")

設置後空格需以 r'\ ' 表示。

 


模塊級函數:
可以不編譯匹配器(正則)而直接使用相應函數匹配內容,如:
“m = match(r'ab*', 'abbcabd', re.M)”
“m = search(r'ab*', 'abbcabd', re.M)”
“listAll = findall(r'ab*', 'abbcabd', re.M)”
“iterAll = finditer(r'ab*', 'abbcabd', re.M)”
都將表達式放在第一個參數、字元串在第二個參數、標誌在第三個參數即可。

 

 

 

正則表達式用於處理字元串的re函數:

“re.split()”可以以正則表達式匹配的內容為分割符,分割字元串。
如:
“p = re.compile(r'\W+')”
“listS = p.split("This is short and sweet.")”
結果為:['This', 'is', 'short', 'and', 'sweet', '']

可指定其最大分割次數,如:
“p.split("This is short and sweet.", maxsplit=2)”指split最多分割2兩次,
得:['This', 'is', 'short and sweet.']
也可寫為“p.split("This is short and sweet.", 2)”

若正則中有捕獲分組,則還將返回捕獲分組的內容,如:
“p2 = re.compile(r'(\W+)')”
“listS2 = p2.split("This is short and sweet.")”
結果為:['This', ' ', 'is', ' ', 'short', ' ', 'and', ' ', 'sweet', '.', '']

 

 

“re.sub()”可將正則在字元串中匹配到的內容替換為另一個內容。
如:
“p = re.compile('(blue|white|red)')”
“s = p.sub('colour', 'blue socks and red shoes')”
結果為:'colour socks and colour shoes'

sub()同樣可指定最大替換次數,如:
“p.sub('colour', 'blue socks and red shoes', count=1)”指sub最多替換1次,
得:'colour socks and red shoes'
也可寫為“p.sub('colour', 'blue socks and red shoes', 1)”

所替換成的另一個內容中可引用匹配內容中的分組內容,可寫為 '\1' 或 '\g<1>' ,表示引用第一個分組。對於命名組 '(?P<name>...)' 還可寫為 '\g<name>' ,如:
“p = re.compile('section{ (?P<name> [^}]* ) }', re.X)”
“p.sub(r'subsection{\1}','section{First}')”
“p.sub(r'subsection{\g<1>}','section{First}')”
“p.sub(r'subsection{\g<name>}','section{First}')”
結果均為:'subsection{First}'

還可為sub()傳入一個函數,sub()會將匹配到的每一個內容以match對象的方式,傳入函數中,然後將匹配的內容替換為函數的返回值。如:
“p = re.compile(r'\d+')”
“p.sub(func, 'Call 65490 for printing, 49152 for user code.')”
可依次將匹配到的 '65490'、'49152' 作為 match 對象,傳入 func 函數。
若 func = lambda m: hex(int(m.group())) ,則得:
'Call 0xffd2 for printing, 0xc000 for user code.'
此方法可將字元串中的各個整數替換為16進位數

 


“subn()”的用法與sub()完全相同,但還會返回替換次數,如:
“p = re.compile('(blue|white|red)')”
“s = p.subn('colour', 'blue socks and red shoes')”
結果為:('colour socks and colour shoes', 2)

 

 

更多方法/函數
“p.fullmatch()”或“re.fullmatch()”用法與match()一樣,但要求正則與字元串必須從頭到尾完全匹配,否則返回None。相當於在正則末尾加了一個 '\Z'
“p.flags()”獲得匹配器p的所有標誌,返回值可直接傳入compile()
“p.pattern()”獲得匹配器p的正則,以字元串形式返回
“re.escape()”可在字元串中的所有元字元前加 '\' ,避免正則轉義,如“print(re.escape('https://www.python.org'))”得 "https://www\.python\.org"
“re.purge()”可清除正則表達式的緩存


“(?...)”也可用於設置標記,放在正則前。如 '(?aiLmsux)^asd&' 可為 '^asd&' 開啟 re.A ~ re.X 所有標誌。實測效果不太理想。

 

 

 

【例題】

1、 找出一個字元串中所有的數字,其中整數用千分位形式表示,即從個位數起,每3位之間加一個逗號,比如1,000,000,小數用定點十進位表示,並且小數點之前至少有一位數字(比如0.618中的0不可省略)。
如:'1,234.56-234.56=1,000'
返回:['1,234.56', '234.56', '1,000']

解:

1 s = r'1,234.56-234.56=1,000'
2  
3 p = re.compile(r"(\d{1,3}(?:,\d{3})*(?:\.\d+)?)")
4 L = p.findall(s)
5 print(L)

 

 


 

參考:

正則表達式HOWTO — Python 3.10.2 文檔

re --- 正則表達式操作 — Python 3.10.4 文檔


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

-Advertisement-
Play Games
更多相關文章
  • 1.字元集/字元編碼是什麼? 字元集或者說字元編碼就是給字元定義了數值編號以及數值編號存儲格式。 嚴格來說字元集和字元編碼是兩個概念: charset 是 character set 的簡寫,即字元集。 encoding 是 charset encoding 的簡寫,即字元集編碼,簡稱編碼。 字元集 ...
  • vant 的表單校驗 個人理解: 將rules當成一個對象去理解,傳參時可以是整個對象或者對象的某一屬性 常用兩種校驗方式 1, 正則表達式 1.1自定義校驗規則(校驗規格也可傳入多條): 表單: :rules="[{ pattern:ageRules, message: '請填寫密碼' }]" d ...
  • 深居內陸的人們,大概每個人都有過大海之夢吧。夏日傍晚在沙灘漫步奔跑;或是在海上衝浪游泳;或是在海島游玩探險;亦或靜待日出日落……本文使用 React + Three.js 技術棧,實現 3D 海洋和島嶼,主要包含知識點包括:Tone Mapping、Water 類、Sky 類、Shader 著色、S... ...
  • 大家好,我是三友,這篇文章想來跟大家來探討一下,在Java中已經提供了併發安全的集合,為什麼有的場景還需要使用讀寫鎖,直接用併發安全的集合難道不行麽? 在java中,併發安全的集合有很多,這裡我就選用常見的CopyOnWriteArrayList為例,來說明一下讀寫鎖的價值到底提現在哪。 CopyO ...
  • 背景 對外服務的介面為了安全起見,往往需要進行相應的安全處理:數據加密傳輸和身份認證。數據加密傳輸有對稱加密和非對稱加密兩種,為了更加安全起見採用非對稱加密比較好些,身份認證則採用數字簽名可以實現。 程式流程 核心代碼 客戶端 package openapi.client.sdk; import c ...
  • 📕深入學習C++還必須掌握的基礎 掌握形參帶預設的函數 1.給預設值方向:從右向左給預設值; 2.調用效率:如果傳預設值或者立即數(不需要從容器或記憶體取取的數字)的話都是直接將數字直接push進棧;沒有mov彙編指令的操作;(面試回答要往彙編上描述) 3.預設值給的地方:定義和聲明處均可以給預設值 ...
  • argparse是深度學習項目調參時常用的python標準庫,使用argparse後,我們在命令行輸入的參數就可以以這種形式python filename.py --lr 1e-4 --batch_size 32來完成對常見超參數的設置。,一般使用時可以歸納為以下三個步驟 使用步驟: 創建Argum ...
  • 前言 emmmm 沒什麼說的,想說的都在代碼里 環境使用 Python 3.8 解釋器 3.10 Pycharm 2021.2 專業版 selenium 3.141.0 本次要用到selenium模塊,所以請記得提前下載好瀏覽器驅動,配置好環境 對於本篇文章有疑問的同學可以加【資料白嫖、解答交流群: ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...