天天看點

python每天一道面試題25

作者:不Dong就自學

Python中正規表達式常用法?

正規表達式一般兩個用途

一是:檢測某一段字元串是否符合規則,也就是我們常說的“校驗”;

二是:從一大段字元串中找到符合規則的字元串,可以了解為“檢索”。

正規表達式子產品

正規表達式子產品标記:re.A或re.ASCII

re.I或re.IGNORECASE忽略大小寫

re.M或re.MULTILINE 使^在起始處并在每個換行符後比對,使$在結尾處但在每個換行符之前比對

re.S或re.DOTALL 使.比對每個字元,包括換行符

re.X或re.VERBOSE 使空白與注釋包含在比對中

正規表達式子產品的函數

re.compile(r,f) :傳回編譯後的正規表達式r,如果指定,就将其标記設定為f(即上邊的re.A等,且可同時有多個标記,用|分隔);通常用作預編譯,接下來重複使用時不需再編譯,傳回pattern對象;然後pattern對象可以調用search方法,pattern.search(string)----獲得根據pattern搜尋的字元串;

re.escape(s) :傳回字元串s,其中所有非字母數字的字元都使用反斜線進行了轉義處理,是以,傳回的字元串中沒有特殊的正規表達式字元;

re.findall(r,s,f) :傳回正規表達式r在字元串s中所有非交疊的比對(如果給定f,就受其制約)。如果正規表達式中有捕獲,那麼每次比對都作為一個捕獲元組傳回; re.finditer(r,s,f) 對正規表達式r在字元串s中每個非交疊的比對(如果給定了f,就受其制約),都傳回一個比對對象;

re.match(r,s,f) :如果正規表達式r在字元串s的起始處比對(如果給定f,就受其制約),就傳回一個比對對象(MatchObject),否則傳回None;

re.search(r,s,f) :如果正規表達式r在字元串s的任意位置比對(如果給定f,就受其制約),就傳回一個比對對象,否則傳回None;

re.split(r,s,m) :傳回分割字元串s(在正規表達式r每次出現處進行分割)所産生的字元串的清單,至多分割m次(如果沒有給定m,就盡可能多的分割),如果正規表達式中包含捕獲,就被包含在分割的部分之間;

>>> s="info:xiaoZhang 33 shandong"
>>> import re
>>> res = re.split(r':| ', s)
>>> res
['info', 'xiaoZhang', '33', 'shandong']           

re.sub(r,x,s,m) :對正規表達式r的每次比對(如果給定m,那麼至多m次),傳回字元串s的一個副本,并将其替換為x--這可以是一個字元串,也可以是一個函數;

re.subn(r,x,s,m) 與re.sub()函數相同,差別在于此函數傳回一個二進制組;

貪婪模式和惰性模式

在正則中,預設的比對模式是“貪婪比對”,也就是說,在符合比對規則的前提下盡可能多的去比對字元,但是有些時候,我們不需要比對太多的内容,隻要得到需要的“片段”内容就好了。

而量詞是比對多次的,這時我們可以在量詞的後面加上?就可以讓比對“适可而止”了,這樣的比對規則就是惰性比對

這裡舉一個貪婪比對與惰性比對對比的例子:

有字元串"aasdasdasdxxxxxxasdasd",現在想比對到x結束

(1)用"惰性比對"的話:

文法:a.*?x

說明:遇見一個先檢測是不是x,如果是的話就停止,不是的話就比對

結果:aasdasdasdx

(2)預設的"貪婪比對":

文法:a.*x

說明:這裡會比對後面所有的x

結果:aasdasdasdxxxxxx

總結:

貪婪模式:

定義:正規表達式去比對時,會盡量多的比對符合條件的内容

辨別符:+,?,*,{n},{n,},{n,m}

比對時,如果遇到上述辨別符,代表是貪婪比對,會盡可能多的去比對内容

非貪婪模式:

定義:正規表達式去比對時,會盡量少的比對符合條件的内容 也就是說,一旦發現比對符合要求,立馬就比對成功,而不會繼續比對下去(除非有g,開啟下一組比對)

辨別符:+?,??,*?,{n}?,{n,}?,{n,m}?

可以看到,非貪婪模式的辨別符很有規律,就是貪婪模式的辨別符後面加上一個?

為了加深印象,看下下面的差别:

## 用Python比對HTML tag的時候,<.> 和 <.?> 有什麼差別?
第一個代表貪心比對,第二個代表非貪心;
?在一般正規表達式裡的文法是指的"零次或一次比對左邊的字元或表達式"相當于{0,1}
而當?字尾于*,+,?,{n},{n,},{n,m}之後,則代表非貪心比對模式,也就是說,
盡可能少的比對左邊的字元或表達式,這裡是盡可能少的比對.(任意字元)
是以:第一種寫法是,盡可能多的比對,就是比對到的字元串盡量長,
第二種寫法是盡可能少的比對,就是比對到的字元串盡量短。
比如<tag>tag>tag>end,第一個會比對<tag>tag>tag>,第二個會比對<tag>。           

re子產品實作正則的功能簡單舉例

re子產品實作正則的功能

re.match(正規表達式,要比對的字元串,[比對模式])

要比對的字元串為str1 = "Python's features"

正規表達式r'(.*)on(.*?) .*'

r表示後面的字元串是一個普通字元串(比如\n會譯為\和n,而不是換行符)

()符号包住的資料為要提取的資料,通常與.group()函數連用。

.比對單個任意字元

*比對前一個字元出現0次或無限次

?比對前一個字元出現0次或1次

(.*)提取的資料為str1字元串中on左邊的所有字元,即Pyth

(.*?)提取的資料為str1中on右邊,空格前面,即's

.group(0)輸出的是比對正規表達式整體結果

.group(1) 列出第一個括号比對部分

.group(2) 列出第二個括号比對部分

re.match與re.search的差別

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

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 --> searchObj.group() : ", matchObj.group())
else:
    print("No match!!")
# 輸出
No match!!
search --> searchObj.group() : dogs           

正規表達式中的特殊字元

$----->比對輸入字元串的結尾位置。如果設定了 RegExp 對象的 Multiline 屬性,則 $ 也比對 '\n' 或 '\r'。要比對 $ 字元本身,請使用\$。

( )----->标記一個子表達式的開始和結束位置。子表達式可以擷取供以後使用。要比對這些字元,請使用 \( 和 \)。

*----->比對前面的子表達式零次或多次。要比對 * 字元,請使用 \*。例如,zo* 能比對 "z" 以及 "zoo"。* 等價于{0,}。

+----->比對前面的子表達式一次或多次。要比對 + 字元,請使用 \+。例如,'zo+' 能比對 "zo" 以及 "zoo",但不能比對 "z"。+ 等價于 {1,}。

.----->比對除換行符 \n 之外的任何單字元。要比對 . ,請使用 \. 。

[----->标記一個中括号表達式的開始。要比對 [,請使用 \[。

?----->比對前面的子表達式零次或一次,或指明一個非貪婪限定符。要比對 ? 字元,請使用 \?。例如,"do(es)?" 可以比對 "do" 、 "does" 中的 "does" 、 "doxy" 中的 "do" 。? 等價于 {0,1}。

\----->将下一個字元标記為或特殊字元、或原義字元、或向後引用、或八進制轉義符。例如, 'n' 比對字元 'n'。'\n' 比對換行符。序列 '\\' 比對 "\",而 '\(' 則比對 "("。

^----->比對輸入字元串的開始位置,除非在方括号表達式中使用,當該符号在方括号表達式中使用時,表示不接受該方括号表達式中的字元集合。要比對 ^ 字元本身,請使用 \^。

{----->标記限定符表達式的開始。要比對 {,請使用 \{。

|----->指明兩項之間的一個選擇。要比對 |,請使用 \|。

{n}----->n 是一個非負整數。比對确定的 n 次。例如,'o{2}' 不能比對 "Bob" 中的 'o',但是能比對 "food" 中的兩個 o。

{n,}----->n 是一個非負整數。至少比對n 次。例如,'o{2,}' 不能比對 "Bob" 中的 'o',但能比對 "foooood" 中的所有 o。'o{1,}' 等價于 'o+'。'o{0,}' 則等價于 'o*'。

{n,m}----->m 和 n 均為非負整數,其中n <= m。最少比對 n 次且最多比對 m 次。例如,"o{1,3}" 将比對 "fooooood" 中的前三個 o。'o{0,1}' 等價于 'o?'。請注意在逗号和兩個數之間不能有空格。

[ABC]----->比對 [...] 中的所有字元,例如 [aeiou] 比對字元串 "google runoob taobao" 中所有的 e o u a 字母。

[^ABC]----->比對除了 [...] 中字元的所有字元,例如 [^aeiou] 比對字元串 "google runoob taobao" 中除了 e o u a 字母的所有字母。

[A-Z]----->[A-Z] 表示一個區間,比對所有大寫字母,[a-z] 表示所有小寫字母。

[\s\S]----->比對所有。\s 是比對所有空白符,包括換行,\S 非空白符,包括換行。

\w----->比對字母、數字、下劃線。等價于 [A-Za-z0-9_]

非列印字元也可以是正規表達式的組成部分。下表列出了表示非列印字元的轉義序列:

\cx----->比對由x指明的控制字元。例如, \cM 比對一個 Control-M 或回車符。x 的值必須為 A-Z 或 a-z 之一。否則,将 c 視為一個原義的 'c' 字元。

\f----->比對一個換頁符。等價于 \x0c 和 \cL。

\n----->比對一個換行符。等價于 \x0a 和 \cJ。

\r----->比對一個回車符。等價于 \x0d 和 \cM。

\s----->比對任何空白字元,包括空格、制表符、換頁符等等。等價于 [ \f\n\r\t\v]。注意 Unicode 正規表達式會比對全角空格符。

\S----->比對任何非空白字元。等價于 [^ \f\n\r\t\v]。

\t----->比對一個制表符。等價于 \x09 和 \cI。

\v----->比對一個垂直制表符。等價于 \x0b 和 \cK。