正則表達(dá)式的入門使用分享


概念

正則表達(dá)式(regular expression)描述了一種字符串匹配的模式(pattern),可以用來檢查一個串是否含有某種子串、將匹配的子串替換或者從某個串中取出符合某個條件的子串等。


一、簡介

除非您以前使用過正則表達(dá)式,否則您可能不熟悉一些術(shù)語。但是,毫無疑問,您已經(jīng)使用過不涉及腳本的某些正則表達(dá)式概念。

例如,您很可能使用 ? 和 * 通配符來查找硬盤上的文件。? 通配符匹配文件名中的 0 個或 1 個字符,而 * 通配符匹配零個或多個字符。像 data(\w)?.dat這樣的模式將查找下列文件:

data.dat
data1.dat
data2.dat
datax.dat
dataN.dat

使用 * 字符代替 ? 字符擴(kuò)大了找到的文件的數(shù)量。data.*.dat 匹配下列所有文件:

data.dat
data1.dat
data2.dat
data12.dat
datax.dat
dataXYZ.dat

盡管這種搜索方法很有用,但它還是有限的。通過理解 * 通配符的工作原理,引入了正則表達(dá)式所依賴的概念,但正則表達(dá)式功能更強大,而且更加靈活。
正則表達(dá)式的使用,可以通過簡單的辦法來實現(xiàn)強大的功能。下面先給出一個簡單的示例:

^[0-9]+abc$

  • ^ :為匹配輸入字符串的開始位置。
  • [0-9]+:匹配多個數(shù)字, [0-9] 匹配單個數(shù)字,+ 匹配一個或者多個。
  • abc$ :匹配字母 abc 并以 abc 結(jié)尾,$ 為匹配輸入字符串的結(jié)束位置。

我們在寫用戶注冊表單時,只允許用戶名包含字符、數(shù)字、下劃線和連接字符(-),并設(shè)置用戶名的長度,我們就可以使用以下正則表達(dá)式來設(shè)定:


1.jpg

以上的正則表達(dá)式可以匹配 runoob、runoob1、run-oob、run_oob, 但不匹配 ru,因為它包含的字母太短了,小于 3 個無法匹配。也不匹配 runoob$, 因為它包含特殊字符。

實例
匹配以數(shù)字開頭,并以 abc 結(jié)尾的字符串:

var str = "123abc";
var patt1 = /^[0-9]+abc$/;
document.write(str.match(patt1));

# 以下標(biāo)記的文本是獲得的匹配的表達(dá)式:
123abc 

為什么使用正則表達(dá)式?

典型的搜索和替換操作要求您提供與預(yù)期的搜索結(jié)果匹配的確切文本。雖然這種技術(shù)對于對靜態(tài)文本執(zhí)行簡單搜索和替換任務(wù)可能已經(jīng)足夠了,但它缺乏靈活性,若采用這種方法搜索動態(tài)文本,即使不是不可能,至少也會變得很困難。

通過使用正則表達(dá)式,可以:

  • 測試字符串內(nèi)的模式。
    -- 例如,可以測試輸入字符串,以查看字符串內(nèi)是否出現(xiàn)電話號碼模式或信用卡號碼模式。這稱為數(shù)據(jù)驗證。
  • 替換文本。
    -- 可以使用正則表達(dá)式來識別文檔中的特定文本,完全刪除該文本或者用其他文本替換它。
  • 基于模式匹配從字符串中提取子字符串。
    -- 可以查找文檔內(nèi)或輸入域內(nèi)特定的文本。
    例如,您可能需要搜索整個網(wǎng)站,刪除過時的材料,以及替換某些 HTML 格式標(biāo)記。在這種情況下,可以使用正則表達(dá)式來確定在每個文件中是否出現(xiàn)該材料或該 HTML 格式標(biāo)記。此過程將受影響的文件列表縮小到包含需要刪除或更改的材料的那些文件。然后可以使用正則表達(dá)式來刪除過時的材料。最后,可以使用正則表達(dá)式來搜索和替換標(biāo)記。

二、語法

構(gòu)造正則表達(dá)式的方法和創(chuàng)建數(shù)學(xué)表達(dá)式的方法一樣。也就是用多種元字符與運算符可以將小的表達(dá)式結(jié)合在一起來創(chuàng)建更大的表達(dá)式。正則表達(dá)式的組件可以是單個的字符、字符集合、字符范圍、字符間的選擇或者所有這些組件的任意組合。

正則表達(dá)式是由普通字符(例如字符 a 到 z)以及特殊字符(稱為"元字符")組成的文字模式。模式描述在搜索文本時要匹配的一個或多個字符串。正則表達(dá)式作為一個模板,將某個字符模式與所搜索的字符串進(jìn)行匹配。

普通字符

普通字符包括沒有顯式指定為元字符的所有可打印和不可打印字符。這包括所有大寫和小寫字母、所有數(shù)字、所有標(biāo)點符號和一些其他符號。

非打印字符

非打印字符也可以是正則表達(dá)式的組成部分。下表列出了表示非打印字符的轉(zhuǎn)義序列:


2.jpg

特殊字符

所謂特殊字符,就是一些有特殊含義的字符,如上面說的 runoo*b 中的 ,簡單的說就是表示任何字符串的意思。如果要查找字符串中的 * 符號,則需要對 * 進(jìn)行轉(zhuǎn)義,即在其前加一個 : runo*ob 匹配 runoob。

許多元字符要求在試圖匹配它們時特別對待。若要匹配這些特殊字符,必須首先使字符"轉(zhuǎn)義",即,將反斜杠字符\ 放在它們前面。下表列出了正則表達(dá)式中的特殊字符:


3.jpg

限定符

限定符用來指定正則表達(dá)式的一個給定組件必須要出現(xiàn)多少次才能滿足匹配。有 * 或 + 或 ? 或 {n} 或 {n,} 或 {n,m} 共6種。
正則表達(dá)式的限定符有:


4.jpg

以下正則表達(dá)式匹配一個正整數(shù),[1-9]設(shè)置第一個數(shù)字不是 0,[0-9]* 表示任意多個數(shù)字:

/[1-9][0-9]*/

請注意,限定符出現(xiàn)在范圍表達(dá)式之后。因此,它應(yīng)用于整個范圍表達(dá)式,在本例中,只指定從 0 到 9 的數(shù)字(包括 0 和 9)。
這里不使用 + 限定符,因為在第二個位置或后面的位置不一定需要有一個數(shù)字。也不使用 ? 字符,因為使用 ? 會將整數(shù)限制到只有兩位數(shù)。
如果你想設(shè)置 0~99 的兩位數(shù),可以使用下面的表達(dá)式來至少指定一位但至多兩位數(shù)字:

/[0-9]{1,2}/

上面的表達(dá)式的缺點是,只能匹配兩位數(shù)字,而且可以匹配 0、00、01、10 99 的章節(jié)編號仍只匹配開頭兩位數(shù)字。
改進(jìn)下,匹配 1~99 的正整數(shù)表達(dá)式如下:

/[1-9][0-9]?/
# 或者
/[1-9][0-9]{0,1}/

* 和 + 限定符都是貪婪的,因為它們會盡可能多的匹配文字,只有在它們的后面加上一個 ? 就可以實現(xiàn)非貪婪或最小匹配。
貪婪:下面的表達(dá)式匹配從開始小于符號 (<) 到關(guān)閉 h1 標(biāo)記的大于符號 (>) 之間的所有內(nèi)容。

/<.*>/

圖片.png

非貪婪:如果您只需要匹配開始和結(jié)束 h1 標(biāo)簽,下面的非貪婪表達(dá)式只匹配 <h1>。

/<.*?>/
圖片.png

也可以使用以下正則表達(dá)式來匹配 h1 標(biāo)簽,表達(dá)式則是:

/<\w+?>/
圖片.png

通過在 *、+ 或 ? 限定符之后放置 ?,該表達(dá)式從"貪婪"表達(dá)式轉(zhuǎn)換為"非貪婪"表達(dá)式或者最小匹配。

定位符

定位符使您能夠?qū)⒄齽t表達(dá)式固定到行首或行尾。它們還使您能夠創(chuàng)建這樣的正則表達(dá)式,這些正則表達(dá)式出現(xiàn)在一個單詞內(nèi)、在一個單詞的開頭或者一個單詞的結(jié)尾。
定位符用來描述字符串或單詞的邊界,^ 和 $ 分別指字符串的開始與結(jié)束,\b 描述單詞的前或后邊界,\B 表示非單詞邊界。
正則表達(dá)式的定位符有:

5.jpg

注意

  • 不能將限定符與定位符一起使用。由于在緊靠換行或者單詞邊界的前面或后面不能有一個以上位置,因此不允許諸如 ^* 之類的表達(dá)式。
  • 若要匹配一行文本開始處的文本,請在正則表達(dá)式的開始使用 ^ 字符。不要將 ^ 的這種用法與中括號表達(dá)式內(nèi)的用法混淆。
  • 若要匹配一行文本的結(jié)束處的文本,請在正則表達(dá)式的結(jié)束處使用 $ 字符。
  • 若要在搜索章節(jié)標(biāo)題時使用定位點,下面的正則表達(dá)式匹配一個章節(jié)標(biāo)題,該標(biāo)題只包含兩個尾隨數(shù)字,并且出現(xiàn)在行首:
/^Chapter [1-9][0-9]{0,1}/

真正的章節(jié)標(biāo)題不僅出現(xiàn)行的開始處,而且它還是該行中僅有的文本。它即出現(xiàn)在行首又出現(xiàn)在同一行的結(jié)尾。下面的表達(dá)式能確保指定的匹配只匹配章節(jié)而不匹配交叉引用。
通過創(chuàng)建只匹配一行文本的開始和結(jié)尾的正則表達(dá)式,就可做到這一點:

/^Chapter [1-9][0-9]{0,1}$/

匹配單詞邊界稍有不同,但向正則表達(dá)式添加了很重要的能力。單詞邊界是單詞和空格之間的位置。非單詞邊界是任何其他位置。下面的表達(dá)式匹配單詞 Chapter 的開頭三個字符,因為這三個字符出現(xiàn)在單詞邊界后面:

/\bCha/

\b 字符的位置是非常重要的。如果它位于要匹配的字符串的開始,它在單詞的開始處查找匹配項。如果它位于字符串的結(jié)尾,它在單詞的結(jié)尾處查找匹配項。例如,下面的表達(dá)式匹配單詞 Chapter 中的字符串 ter,因為它出現(xiàn)在單詞邊界的前面:

/ter\b/

下面的表達(dá)式匹配 Chapter 中的字符串 apt,但不匹配 aptitude 中的字符串 apt:

/\Bapt/

字符串 apt 出現(xiàn)在單詞 Chapter 中的非單詞邊界處,但出現(xiàn)在單詞 aptitude 中的單詞邊界處。對于 \B 非單詞邊界運算符,位置并不重要,因為匹配不關(guān)心究竟是單詞的開頭還是結(jié)尾。

選擇

用圓括號將所有選擇項括起來,相鄰的選擇項之間用|分隔。但用圓括號會有一個副作用,使相關(guān)的匹配會被緩存,此時可用?:放在第一個選項前來消除這種副作用。

其中 ?: 是非捕獲元之一,還有兩個非捕獲元是 ?= 和 ?!,這兩個還有更多的含義,前者為正向預(yù)查,在任何開始匹配圓括號內(nèi)的正則表達(dá)式模式的位置來匹配搜索字符串,后者為負(fù)向預(yù)查,在任何開始不匹配該正則表達(dá)式模式的位置來匹配搜索字符串。

反向引用

對一個正則表達(dá)式模式或部分模式兩邊添加圓括號將導(dǎo)致相關(guān)匹配存儲到一個臨時緩沖區(qū)中,所捕獲的每個子匹配都按照在正則表達(dá)式模式中從左到右出現(xiàn)的順序存儲。緩沖區(qū)編號從 1 開始,最多可存儲 99 個捕獲的子表達(dá)式。每個緩沖區(qū)都可以使用 \n 訪問,其中 n 為一個標(biāo)識特定緩沖區(qū)的一位或兩位十進(jìn)制數(shù)。
可以使用非捕獲元字符 ?:、?= 或 ?! 來重寫捕獲,忽略對相關(guān)匹配的保存。
反向引用的最簡單的、最有用的應(yīng)用之一,是提供查找文本中兩個相同的相鄰單詞的匹配項的能力。以下面的句子為例:

Is is the cost of of gasoline going up up?

上面的句子很顯然有多個重復(fù)的單詞。如果能設(shè)計一種方法定位該句子,而不必查找每個單詞的重復(fù)出現(xiàn),那該有多好。下面的正則表達(dá)式使用單個子表達(dá)式來實現(xiàn)這一點:

# 查找重復(fù)的單詞:
var str = "Is is the cost of of gasoline going up up";
var patt1 = /\b([a-z]+) \1\b/ig;
document.write(str.match(patt1));

# 運行結(jié)果:
Is is,of of,up up 

捕獲的表達(dá)式,正如 [a-z]+ 指定的,包括一個或多個字母。正則表達(dá)式的第二部分是對以前捕獲的子匹配項的引用,即,單詞的第二個匹配項正好由括號表達(dá)式匹配。\1 指定第一個子匹配項。
單詞邊界元字符確保只檢測整個單詞。否則,諸如 "is issued" 或 "this is" 之類的詞組將不能正確地被此表達(dá)式識別。
正則表達(dá)式后面的全局標(biāo)記 g 指定將該表達(dá)式應(yīng)用到輸入字符串中能夠查找到的盡可能多的匹配。
表達(dá)式的結(jié)尾處的不區(qū)分大小寫 i 標(biāo)記指定不區(qū)分大小寫。
多行標(biāo)記指定換行符的兩邊可能出現(xiàn)潛在的匹配。
反向引用還可以將通用資源指示符 (URI) 分解為其組件。假定您想將下面的 URI 分解為協(xié)議(ftp、http 等等)、域地址和頁/路徑:
http://www.runoob.com:80/html/html-tutorial.html
下面的正則表達(dá)式提供該功能:

# 輸出所有匹配的數(shù)據(jù):
var str = "http://www.runoob.com:80/html/html-tutorial.html";
var patt1 = /(\w+):\/\/([^/:]+)(:\d*)?([^# ]*)/;
arr = str.match(patt1);
for (var i = 0; i < arr.length ; i++) {
    document.write(arr[i]);
    document.write("<br>");
}

# 運行結(jié)果:
http://www.runoob.com:80/html/html-tutorial.html
http
www.runoob.com
:80
/html/html-tutorial.html

第三行代碼 str.match(patt1) 返回一個數(shù)組,實例中的數(shù)組包含 5 個元素,索引 0 對應(yīng)的是整個字符串,索引 1 對應(yīng)第一個匹配符(括號內(nèi)),以此類推。
第一個括號子表達(dá)式捕獲 Web 地址的協(xié)議部分。該子表達(dá)式匹配在冒號和兩個正斜杠前面的任何單詞。
第二個括號子表達(dá)式捕獲地址的域地址部分。子表達(dá)式匹配非 : 和 / 之后的一個或多個字符。
第三個括號子表達(dá)式捕獲端口號(如果指定了的話)。該子表達(dá)式匹配冒號后面的零個或多個數(shù)字。只能重復(fù)一次該子表達(dá)式。
最后,第四個括號子表達(dá)式捕獲 Web 地址指定的路徑和 / 或頁信息。該子表達(dá)式能匹配不包括 # 或空格字符的任何字符序列。
將正則表達(dá)式應(yīng)用到上面的 URI,各子匹配項包含下面的內(nèi)容:

  • 第一個括號子表達(dá)式包含 http
  • 第二個括號子表達(dá)式包含 www.runoob.com
  • 第三個括號子表達(dá)式包含 :80
  • 第四個括號子表達(dá)式包含 /html/html-tutorial.html

三、元字符

下表包含了元字符的完整列表以及它們在正則表達(dá)式上下文中的行為:


圖片.png

四、運算優(yōu)先級

正則表達(dá)式從左到右進(jìn)行計算,并遵循優(yōu)先級順序,這與算術(shù)表達(dá)式非常類似。
相同優(yōu)先級的從左到右進(jìn)行運算,不同優(yōu)先級的運算先高后低。
下表從最高到最低說明了各種正則表達(dá)式運算符的優(yōu)先級順序:


圖片.png

五、匹配規(guī)則

基本匹配模式

模式,是正則表達(dá)式最基本的元素,它們是一組描述字符串特征的字符。模式可以很簡單,由普通的字符串組成,也可以非常復(fù)雜,往往用特殊的字符表示一個范圍內(nèi)的字符、重復(fù)出現(xiàn),或表示上下文。例如:

^once

這個模式包含一個特殊的字符^,表示該模式只匹配那些以once開頭的字符串。例如該模式與字符串"once upon a time"匹配,與"There once was a man from NewYork"不匹配。

正如如^符號表示開頭一樣,$符號用來匹配那些以給定模式結(jié)尾的字符串:

bucket$

這個模式與"Who kept all of this cash in a bucket"匹配,與"buckets"不匹配。

字符 ^ 和 $ 同時使用時,表示精確匹配(字符串與模式一樣)。例如:

^bucket$

只匹配字符串"bucket"。

如果一個模式不包括^和$,那么它與任何包含該模式的字符串匹配。例如:

once

# 與以下字符串都是匹配的:
There once was a man from NewYork
Who kept all of his cash in a bucket.

在該模式中的字母(o-n-c-e)是字面的字符,也就是說,他們表示該字母本身,數(shù)字也是一樣的。其他一些稍微復(fù)雜的字符,如標(biāo)點符號和白字符(空格、制表符等),要用到轉(zhuǎn)義序列。所有的轉(zhuǎn)義序列都用反斜杠()打頭。制表符的轉(zhuǎn)義序列是 \t。所以如果我們要檢測一個字符串是否以制表符開頭,可以用這個模式:

^\t 

類似的,用\n表示"新行",\r表示回車。其他的特殊符號,可以用在前面加上反斜杠,如反斜杠本身用\表示,句號.用.表示,以此類推。

字符簇

在INTERNET的程序中,正則表達(dá)式通常用來驗證用戶的輸入。當(dāng)用戶提交一個FORM以后,要判斷輸入的電話號碼、地址、EMAIL地址、信用卡號碼等是否有效,用普通的基于字面的字符是不夠的。

所以要用一種更自由的描述我們要的模式的辦法,它就是字符簇。要建立一個表示所有元音字符的字符簇,就把所有的元音字符放在一個方括號里:

[AaEeIiOoUu]

這個模式與任何元音字符匹配,但只能表示一個字符。

用連字號可以表示一個字符的范圍,如:

[a-z] //匹配所有的小寫字母 
[A-Z] //匹配所有的大寫字母 
[a-zA-Z] //匹配所有的字母 
[0-9] //匹配所有的數(shù)字 
[0-9\.\-] //匹配所有的數(shù)字,句號和減號 
[ \f\r\t\n] //匹配所有的白字符

同樣的,這些也只表示一個字符。

如果要匹配一個由一個小寫字母和一位數(shù)字組成的字符串,比如"z2"、"t6"或"g7",但不是"ab2"、"r2d3" 或"b52"的話,用這個模式:

^[a-z][0-9]$

盡管[a-z]代表26個字母的范圍,但在這里它只能與第一個字符是小寫字母的字符串匹配。

前面曾經(jīng)提到^表示字符串的開頭,但它還有另外一個含義。當(dāng)在一組方括號里使用 ^ 時,它表示"非"或"排除"的意思,常常用來剔除某個字符。還用前面的例子,我們要求第一個字符不能是數(shù)字:

^[^0-9][0-9]$

這個模式與"&5"、"g7"及"-2"是匹配的,但與"12"、"66"是不匹配的。

下面是幾個排除特定字符的例子:

[^a-z] //除了小寫字母以外的所有字符 
[^\\\/\^] //除了(\)(/)(^)之外的所有字符 
[^\"\'] //除了雙引號(")和單引號(')之外的所有字符

特殊字符 .(點,句號)在正則表達(dá)式中用來表示除了"新行"之外的所有字符。所以模式 ^.5$ 與任何兩個字符的、以數(shù)字5結(jié)尾和以其他非"新行"字符開頭的字符串匹配。模式 . 可以匹配任何字符串,除了空串和只包括一個"新行"的字符串。

確定重復(fù)出現(xiàn)

到現(xiàn)在為止,你已經(jīng)知道如何去匹配一個字母或數(shù)字,但更多的情況下,可能要匹配一個單詞或一組數(shù)字。一個單詞有若干個字母組成,一組數(shù)字有若干個單數(shù)組成。跟在字符或字符簇后面的花括號({})用來確定前面的內(nèi)容的重復(fù)出現(xiàn)的次數(shù)。


圖片.png

這些例子描述了花括號的三種不同的用法。一個數(shù)字 {x} 的意思是前面的字符或字符簇只出現(xiàn)x次 ;一個數(shù)字加逗號 {x,} 的意思是前面的內(nèi)容出現(xiàn)x或更多的次數(shù) ;兩個數(shù)字用逗號分隔的數(shù)字 {x,y} 表示 前面的內(nèi)容至少出現(xiàn)x次,但不超過y次。

我們可以把模式擴(kuò)展到更多的單詞或數(shù)字:

# 所有包含一個以上的字母、數(shù)字或下劃線的字符串 
^[a-zA-Z0-9_]{1,}$    

# 所有的正整數(shù)  
^[1-9][0-9]{0,}$  

# 所有的整數(shù)    
^\-{0,1}[0-9]{1,}$

# 所有的浮點數(shù)
^[-]?[0-9]+\.?[0-9]+$   

//

最后一個例子不太好理解,是嗎?這么看吧:以一個可選的負(fù)號 ([-]?) 開頭 (^)、跟著1個或更多的數(shù)字([0-9]+)、和一個小數(shù)點(.)再跟上1個或多個數(shù)字([0-9]+),并且后面沒有其他任何東西($)。

注意:

  • 特殊字符 ? 與 {0,1} 是相等的:
    表示0個或1個前面的內(nèi)容 或 這些內(nèi)容是可選的 。
  • 特殊字符 * 與 {0,} 是相等的:
    表示0 個或多個前面的內(nèi)容 。
  • 特殊字符 + 與 {1,} 是相等的:
    表示 1 個或多個前面的內(nèi)容 。

所以上面的4個例子可以寫成:

# 所有包含一個以上的字母、數(shù)字或下劃線的字符串 
^[a-zA-Z0-9_]+$

# 所有的正整數(shù)  
^[1-9][0-9]*$

# 所有的整數(shù)    
^[-]?[0-9]+$

# 所有的浮點數(shù)
^[-]?[0-9]+[.][0-9]+$

//

當(dāng)然這并不能從技術(shù)上降低正則表達(dá)式的復(fù)雜性,但可以使它們更容易閱讀。


六、Python3 的正則表達(dá)式

Python 自1.5版本起增加了re 模塊,它提供 Perl 風(fēng)格的正則表達(dá)式模式。

re 模塊使 Python 語言擁有全部的正則表達(dá)式功能。
compile 函數(shù)根據(jù)一個模式字符串和可選的標(biāo)志參數(shù)生成一個正則表達(dá)式對象。該對象擁有一系列方法用于正則表達(dá)式匹配和替換。
re 模塊也提供了與這些方法功能完全一致的函數(shù),這些函數(shù)使用一個模式字符串做為它們的第一個參數(shù)。

re.match函數(shù)

re.match 嘗試從字符串的起始位置匹配一個模式,如果不是起始位置匹配成功的話,match()就返回none。
函數(shù)語法:

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

函數(shù)參數(shù)說明:


圖片.png

匹配成功re.match方法返回一個匹配的對象,否則返回None。

我們可以使用group(num) 或 groups() 匹配對象函數(shù)來獲取匹配表達(dá)式:


圖片.png

實例1:

#!/usr/bin/python
 
import re
print(re.match('www', 'www.runoob.com').span())  # 在起始位置匹配
print(re.match('com', 'www.runoob.com'))         # 不在起始位置匹配

# 以上實例運行輸出結(jié)果為:
(0, 3)
None

實例2:

#!/usr/bin/python3
import re
 
line = "Cats are smarter than dogs"
# .* 表示任意匹配除換行符(\n、\r)之外的任何單個或多個字符
matchObj = re.match( r'(.*) are (.*?) .*', line, re.M|re.I)
 
if matchObj:
   print ("matchObj.group() : ", matchObj.group())
   print ("matchObj.group(1) : ", matchObj.group(1))
   print ("matchObj.group(2) : ", matchObj.group(2))
else:
   print ("No match!!")

# 以上實例執(zhí)行結(jié)果如下:
matchObj.group() :  Cats are smarter than dogs
matchObj.group(1) :  Cats
matchObj.group(2) :  smarter

re.search方法

re.search 掃描整個字符串并返回第一個成功的匹配。
函數(shù)語法:

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

函數(shù)參數(shù)說明:


圖片.png

匹配成功re.search方法返回一個匹配的對象,否則返回None。

我們可以使用group(num) 或 groups() 匹配對象函數(shù)來獲取匹配表達(dá)式:

圖片.png

實例1:

#!/usr/bin/python3
 
import re
 
print(re.search('www', 'www.runoob.com').span())  # 在起始位置匹配
print(re.search('com', 'www.runoob.com').span())         # 不在起始位置匹配

# 以上實例運行輸出結(jié)果為:
(0, 3)
(11, 14)

實例2:


#!/usr/bin/python3
 
import re
 
line = "Cats are smarter than dogs"
 
searchObj = re.search( r'(.*) are (.*?) .*', line, re.M|re.I)
 
if searchObj:
   print ("searchObj.group() : ", searchObj.group())
   print ("searchObj.group(1) : ", searchObj.group(1))
   print ("searchObj.group(2) : ", searchObj.group(2))
else:
   print ("Nothing found!!")

# 以上實例執(zhí)行結(jié)果如下:
searchObj.group() :  Cats are smarter than dogs
searchObj.group(1) :  Cats
searchObj.group(2) :  smarter

re.match與re.search的區(qū)別

re.match 只匹配字符串的開始,如果字符串開始不符合正則表達(dá)式,則匹配失敗,函數(shù)返回 None,
而 re.search 匹配整個字符串,直到找到一個匹配。
實例:

#!/usr/bin/python3
 
import re
 
line = "Cats are smarter than dogs"

matchObj = re.match( r'dogs', line, re.M|re.I)
if matchObj:
   print ("match --> matchObj.group() : ", matchObj.group())
else:
   print ("No match!!")
 
matchObj = re.search( r'dogs', line, re.M|re.I)
if matchObj:
   print ("search --> matchObj.group() : ", matchObj.group())
else:
   print ("No match!!")

# 以上實例運行結(jié)果如下:
No match!!
search --> matchObj.group() :  dogs

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。