python正則表達式入門篇

来源:https://www.cnblogs.com/gufengchen/archive/2019/05/23/10915090.html
-Advertisement-
Play Games

<!--done--> 文章來源於:https://www.cnblogs.com/chuxiuhong/p/5885073.html Python 正則表達式入門(初級篇) 本文主要為沒有使用正則表達式經驗的新手入門所寫。 轉載請寫明出處 引子 首先說 正則表達式是什麼? 正則表達式,又稱正規表示 ...


文章來源於:https://www.cnblogs.com/chuxiuhong/p/5885073.html

Python 正則表達式入門(初級篇)

本文主要為沒有使用正則表達式經驗的新手入門所寫。
轉載請寫明出處

引子

首先說 正則表達式是什麼?

正則表達式,又稱正規表示式、正規表示法、正規表達式、規則表達式、常規表示法(英語:Regular Expression,在代碼中常簡寫為regex、regexp或RE),電腦科學的一個概念。正則表達式使用單個字元串來描述、匹配一系列匹配某個句法規則的字元串。在很多文本編輯器里,正則表達式通常被用來檢索、替換那些匹配某個模式的文本。
許多程式設計語言都支持利用正則表達式進行字元串操作。例如,在Perl中就內建了一個功能強大的正則表達式引擎。正則表達式這個概念最初是由Unix中的工具軟體(例如sed和grep)普及開的。正則表達式通常縮寫成“regex”,單數有regexp、regex,複數有regexps、regexes、regexen。
引用自維基百科https://zh.wikipedia.org/wiki/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F

定義是定義,太正經了就沒法用了。我們來舉個慄子:假如你在寫一個爬蟲,你得到了
一個網頁的HTML源碼。其中有一段

<html><body><h1>hello world<h1></body></html>

你想要把這個hello world提取出來,但你這時如果只會python 的字元串處理,那麼第一反應可能是

s = <html><body><h1>hello world<h1></body></html>
start_index = s.find('<h1>')

然後從這個位置向下查找到下一個<h1>出現這樣做未嘗不可,但是很麻煩不是嗎。需要考慮多個標簽,一不留神就多匹配到東西了,而如果想要非常準確的匹配到,又得多加迴圈判斷,效率太低。

這時候,正則表達式就是首選的幫手。

乾貨開始


入門級別


接著說我們剛纔那個例子。我們如果拿正則處理這個表達式要怎麼做呢?

import re

key = r"<html><body><h1>hello world<h1></body></html>"#這段是你要匹配的文本
p1 = r"(?<=<h1>).+?(?=<h1>)"#這是我們寫的正則表達式規則,你現在可以不理解啥意思
pattern1 = re.compile(p1)#我們在編譯這段正則表達式
matcher1 = re.search(pattern1,key)#在源文本中搜索符合正則表達式的部分
print matcher1.group(0)#列印出來

你可以嘗試運行上面的代碼,看看是不是和我們想象的一樣(博主是在python2.7環境下)發現代碼挺少挺簡單?往下看。而且正則表達式實際上要比看起來的那種奇形怪狀要簡單得多。

首先,從最基礎的正則表達式說起。
假設我們的想法是把一個字元串中的所有"python"給匹配到。我們試一試怎麼做

import re

key = r"javapythonhtmlvhdl"#這是源文本
p1 = r"python"#這是我們寫的正則表達式
pattern1 = re.compile(p1)#同樣是編譯
matcher1 = re.search(pattern1,key)#同樣是查詢
print matcher1.group(0)

看完這段代碼,你是不是覺得:卧槽?這就是正則表達式?直接寫上去就行?
確實,正則表達式並不像它錶面上那麼奇葩,如果不是我們故意改變一些符號的含義時,你看到的就是想要匹配的。
所以,先把大腦清空,先認為正則表達式就是和想要匹配的字元串長得一樣。在之後的練習中我們會逐步進化


初級


0.無論是python還是正則表達式都是區分大小寫的,所以當你在上面那個例子上把"python"換成了"Python",那就匹配不到你心愛的python了。

1.重新回到第一個例子中那個<h1>hello world<h1>匹配。假如我像這麼寫,會怎麼樣?

import re

key = r"<h1>hello world<h1>"#源文本
p1 = r"<h1>.+<h1>"#我們寫的正則表達式,下麵會將為什麼
pattern1 = re.compile(p1)
print pattern1.findall(key)#發沒發現,我怎麼寫成findall了?咋變了呢?

有了入門級的經驗,我們知道那兩個<h1>就是普普通通的字元,但是中間的是什麼鬼?
.字元在正則表達式代表著可以代表任何一個字元(包括它本身)
findall返回的是所有符合要求的元素列表,包括僅有一個元素時,它還是給你返回的列表。

機智如你可能會突然問:那我如果就只是想匹配"."呢?結果啥都給我返回了咋整?在正則表達式中有一個字元\,其實如果你編程經驗較多的話,你就會發現這是好多地方的“轉義符”。在正則表達式里,這個符號通常用來把特殊的符號轉成普通的,把普通的轉成特殊的23333(並不是特殊的“2333”,寫完才發現會不會有腦洞大的想歪了)。
舉個慄子,你真的想匹配"[email protected]"這個郵箱(我的郵箱),你可以把正則表達式寫成下麵這個樣子:

import re

key = r"[email protected]"
p1 = r"chuxiuhong@hit\.edu\.cn"
pattern1 = re.compile(p1)
print pattern1.findall(key)

發現了吧,我們在.的前面加上了轉義符\,但是並不是代表匹配“\.”的意思,而是匹配“.”的意思!
不知道你細不細心,有沒有發現我們第一次用.時,後面還跟了一個+?那這個加號是乾什麼的呢?
其實不難想,我們說了“.字元在正則表達式代表著可以代表任何一個字元(包括它本身)”,但是"hello world"可不是一個字元啊。
+的作用是將前面一個字元或一個子表達式重覆一遍或者多遍。
比方說表達式“ab+”那麼它能匹配到“abbbbb”,但是不能匹配到"a",它要求你必須得有個b,多了不限,少了不行。你如果問我有沒有那種“有沒有都行,有多少都行的表達方式”,回答是有的。
*跟在其他符號後面表達可以匹配到它0次或多次
比方說我們在王葉內遇到了鏈接,可能既有http://開頭的,又有https://開頭的,我們怎麼處理?

import re

key = r"http://www.nsfbuhwe.com and https://www.auhfisna.com"#胡編亂造的網址,別在意
p1 = r"https*://"#看那個星號!
pattern1 = re.compile(p1)
print pattern1.findall(key)

輸出

['http://', 'https://']

2.比方說我們有這麼一個字元串"cat hat mat qat",你會發現前面三個是實際的單詞,最後那個是我胡編亂造的(上百度查完是昆士蘭英語學院的縮寫= =)。如果你本來就知道"at"前面是c、h、m其中之一時這才構成單詞,你想把這樣的匹配出來。根據已經學到的知識是不是會想到寫出來三個正則表達式進行匹配?實際上不需要。因為有一種多字元匹方式
[]代表匹配裡面的字元中的任意一個
還是舉個慄子,我們發現啊,有的程式員比較過分,,在<html></html>這對標簽上,大小寫混用,老害得我們抓不到想要的東西,我們該怎麼應對?是寫16*16種正則表達式挨個匹配?no

import re

key = r"lalala<hTml>hello</Html>heiheihei"
p1 = r"<[Hh][Tt][Mm][Ll]>.+?</[Hh][Tt][Mm][Ll]>"
pattern1 = re.compile(p1)
print pattern1.findall(key)

輸出

['<hTml>hello</Html>']

我們既然有了範圍性的匹配,自然有範圍性的排除。
[^]代表除了內部包含的字元以外都能匹配
還是cat,hat,mat,qat這個例子,我們想匹配除了qat以外的,那麼就應該這麼寫:

import re

key = r"mat cat hat pat"
p1 = r"[^p]at"#這代表除了p以外都匹配
pattern1 = re.compile(p1)
print pattern1.findall(key)

輸出
為了方便我們寫簡潔的正則表達式,它本身還提供下麵這樣的寫法

正則表達式代表的匹配字元
[0-9] 0123456789任意之一
[a-z] 小寫字母任意之一
[A-Z] 大寫字母任意之一
\d 等同於[0-9]
\D 等同於[^0-9]匹配非數字
\w 等同於[a-z0-9A-Z_]匹配大小寫字母、數字和下劃線
\W 等同於[^a-z0-9A-Z_]等同於上一條取非

3.介紹到這裡,我們可能已經掌握了大致的正則表達式的構造方式,但是我們常常會在實戰中遇到一些匹配的不准確的問題。比方說:

import re

key = r"[email protected]"
p1 = r"@.+\."#我想匹配到@後面一直到“.”之間的,在這裡是hit
pattern1 = re.compile(p1)
print pattern1.findall(key)

輸出結果

['@hit.edu.']

呦呵!你咋能多了呢?我理想的結果是@hit.,你咋還給我加量了呢?這是因為正則表達式預設是“貪婪”的,我們之前講過,“+”代表是字元重覆一次或多次。但是我們沒有細說這個多次到底是多少次。所以它會儘可能“貪婪”地多給我們匹配字元,在這個例子里也就是匹配到最後一個“.”。
我們怎麼解決這種問題呢?只要在“+”後面加一個“?”就好了。

import re

key = r"[email protected]"
p1 = r"@.+?\."#我想匹配到@後面一直到“.”之間的,在這裡是hit
pattern1 = re.compile(p1)
print pattern1.findall(key)

輸出結果

['@hit.']

加了一個“?”我們就將貪婪的“+”改成了懶惰的“+”。這對於[abc]+,\w*之類的同樣適用。

小測驗:上面那個例子可以不使用懶惰匹配,想一種方法得到同樣的結果

**個人建議:在你使用"+","*"的時候,一定先想好到底是用貪婪型還是懶惰型,尤其是當你用到範圍較大的項目上時,因為很有可能它就多匹配字元回來給你!!!**

為了能夠準確的控制重覆次數,正則表達式還提供
{a,b}(代表a<=匹配次數<=b)

還是舉個慄子,我們有sas,saas,saaas,我們想要sas和saas,我們怎麼處理呢?


import re

key = r"saas and sas and saaas"
p1 = r"sa{1,2}s"
pattern1 = re.compile(p1)
print pattern1.findall(key)

輸出

['saas', 'sas']

如果你省略掉{1,2}中的2,那麼就代表至少匹配一次,那麼就等價於?
如果你省略掉{1,2}中的1,那麼就代表至多匹配2次。

下麵列舉一些正則表達式里的元字元及其作用

元字元說明
. 代表任意字元
| 邏輯或操作符
[ ] 匹配內部的任一字元或子表達式
[^] 對字元集和取非
- 定義一個區間
\ 對下一字元取非(通常是普通變特殊,特殊變普通)
* 匹配前面的字元或者子表達式0次或多次
*? 惰性匹配上一個
+ 匹配前一個字元或子表達式一次或多次
+? 惰性匹配上一個
? 匹配前一個字元或子表達式0次或1次重覆
{n} 匹配前一個字元或子表達式
{m,n} 匹配前一個字元或子表達式至少m次至多n次
{n,} 匹配前一個字元或者子表達式至少n次
{n,}? 前一個的惰性匹配
^ 匹配字元串的開頭
\A 匹配字元串開頭
$ 匹配字元串結束
[\b] 退格字元
\c 匹配一個控制字元
\d 匹配任意數字
\D 匹配數字以外的字元
\t 匹配製表符
\w 匹配任意數字字母下劃線
\W 不匹配數字字母下劃線

中級篇介紹子表達式,向前向後查找,回溯引用 鏈接:http://www.cnblogs.com/chuxiuhong/p/5907484.html

蒼生苦難,不知伊於胡底
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 積跬步,行千里,先從最簡單的開始寫。 這一篇介紹V8中的時間模塊,與libuv粗糙的update_loop_time方法不同,V8有一套獨立完整的類負責管理時間。 該類位於src/base/platform/time.h,是一個輔助模塊,首先來看一下繼承樹。 整個模塊的繼承關係比較簡單,一般常用的就 ...
  • 統計字元串中每一個不同的字元 JDK9的新特性: List介面,Set介面,Map介面裡邊增加了一個靜態方法of,可以給集合一次性添加多個元素 使用前提:當集合中存儲的元素的個數已經確定了,不再改變使用,也就是說,添加完元素之後,就不能再使用put方法來添加元素了 註意事項: 1. of方法只適用於 ...
  • 伺服器免密登錄 由於有多台伺服器,每次登錄還需要 去找對應的伺服器地址,然後輸入密碼,為了避免麻煩,就使用了免密登錄。普通登錄方式: ssh -p 22 [email protected] 每次登錄還需要輸入密碼,比較麻煩 更換免密碼登錄: 本地操作: 本地的公鑰位置: ~/.ssh/i... ...
  • 今天工作的時候接觸到客戶的一臺伺服器,業務邏輯比較簡單 。估算pv在120w左右吧,用的是阿裡雲2c4g的伺服器。一大早就開始卡頓了,登陸伺服器後查看負載到了八九十。 之後就想辦法調整一下吧。突然想起某位前輩說過的:開啟opcache吧,真的會變快的。 於是我馬上就開始整,過程很簡單 1.進入php ...
  • 對於Java初學者,可能會面對這麼一個問題,Java環境的配置,那麼廢話少說,直接開始。首先找到jdk的安裝包(我這邊以jdk1.8為例),雙擊安裝。 到這邊我們的jdk已經成功安裝,但這樣我們有些同學的eclipse依然沒法使用,那是因為eclipse需要配置jdk才能正常使用,下麵開始配置jdk ...
  • 1,函數重寫回顧: 1,父類中被重寫的函數依然會繼承給子類; 2,子類中重寫的函數將覆蓋父類中的函數; 1,重寫父類當中提供的函數是因為父類當中提供的這個函數版本不能滿足我們的需求,因此我們要重寫; 2,期望只要是子類對象,則調用子類當中的版本,而不是父類當中定義的函數版本; 3,通過作用域分辨符( ...
  • 自己動手寫一個鎖需要哪些知識? 自己動手寫一個鎖到底有多簡單? 自己能不能寫出來一個完美的鎖? ...
  • 1,父子間的衝突是由繼承帶來的,兩個類之間存在了繼承的關係,必然的會帶來一 些問題,本文要討論的是父子之間成員變數或成員函數的命名問題; 2,思考: 1,子類中是否可以定義父類中的同名成員? 1,可以,本文先編程解決這個問題; 2,這個問題就是同名覆蓋問題; 2,如果可以,如何區分?如果不可以,為什 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...