Python 正則表達式詳解

正則表達式

    正則表達式是一種用來匹配字符串的強有力的武器。它的設計思想是用一種描述性的語言來給字符串定義一個規則,凡是符合規則的字符串,我們就認爲它“匹配”了,否則,該字符串就是不合法的。

    我們判斷一個字符串是否符合規則的方法是:
        創建一個用於匹配的正則表達式
        用該正則表達式去匹配字符串判斷是否合法。

    因爲正則表達式也是用字符串表示的,所以,我們要首先了解如何用字符來描述字符。

特別字符描述
[ ]

[amk] will match 'a', 'm', or 'k'.

[a-z]   [0-9A-Fa-f] 表示範圍匹配,一個[]內有多個範圍時只會從某一個範圍中匹配。[0-5][0-9]

 (+*) 在[]中失去特殊含義  [(+*)] 將會匹配'(', '+', '*', or ')'.

\w or \S等在[] 可以使用

如果[]內的第一個字符是^,那麼表示except。[^5] will match any character except '5'。如果不是第一個字符那麼^失去特殊含義

( )標記一個子表達式(Group)的開始和結束位置。子表達式可以獲取供以後使用。要匹配這些字符,請使用 \( 和 \)。
*匹配前面的子表達式零次或多次。要匹配 * 字符,請使用 \*。
+匹配前面的子表達式一次或多次。要匹配 + 字符,請使用 \+。
.

匹配除換行符 \n 之外的任何單字符。要匹配 . ,請使用 \. 。標誌re.DOTALL表示.可以匹配\n

 


?匹配前面的子表達式零次或一次,或指明一個非貪婪限定符。要匹配 ? 字符,請使用 \?。
\將下一個字符標記爲或特殊字符、或原義字符、或向後引用、或八進制轉義符。例如, 'n' 匹配字符 'n'。'\n' 匹配換行符。序列 '\\' 匹配 "\",而 '\(' 則匹配 "("。
^匹配輸入字符串的開始位置,除非在方括號表達式中使用,此時它表示不接受該字符集合。要匹配 ^ 字符本身,請使用 \^。RE.
$匹配輸入字符串的結尾位置。如果設置了 RegExp 對象的 Multiline 屬性,則 $ 也匹配 '\n' 或 '\r'。要匹配 $ 字符本身,請使用 \$。
|

指明兩項之間的一個選擇。要匹配 |,請使用 \|。

可以分隔任意多個re,例如  A|B|C|D 表示四個任意RE中間選一個, 順序從左到右


    由於Python的字符串本身也用\轉義,因此我們強烈建議使用Python的r前綴,就不用考慮轉義的問題了:例如:如果我們相想匹配一個'\'字符,那麼對應的re pattern是'\\',對應的re str就是'\\\\',相當於需要轉義兩次,而使用了r前綴的話,對應的re str就是r'\\',不用考慮第一次字符串轉義。

字符描述
*匹配前面的子表達式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。* 等價於{0,}。
+匹配前面的子表達式一次或多次。例如,'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等價於 {1,}。
?匹配前面的子表達式零次或一次。例如,"do(es)?" 可以匹配 "do" 、 "does" 中的 "does" 、 "doxy" 中的 "do" 。? 等價於 {0,1}。
{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?'。請注意在逗號和兩個數之間不能有空格。


字符描述
(?P<name>...) 
(pattern)

匹配 pattern 並獲取這一匹配。所獲取的匹配可以從產生的 Matches 集合得到,在VBScript 中使用 SubMatches 集合,在JScript 中則使用 $0…$9 屬性。要匹配圓括號字符,請使用 '\(' 或 '\)'。

(?:pattern)

匹配 pattern 但不獲取匹配結果,也就是說這是一個非獲取匹配,不進行存儲供以後使用。這在使用 "或" 字符 (|) 來組合一個模式的各個部分是很有用。例如, 'industr(?:y|ies) 就是一個比 'industry|industries' 更簡略的表達式。

(?=pattern)

正向肯定預查(look ahead positive assert),在任何匹配pattern的字符串開始處匹配查找字符串。這是一個非獲取匹配,也就是說,該匹配不需要獲取供以後使用。例如,"Windows(?=95|98|NT|2000)"能匹配"Windows2000"中的"Windows",但不能匹配"Windows3.1"中的"Windows"。預查不消耗字符,也就是說,在一個匹配發生後,在最後一次匹配之後立即開始下一次匹配的搜索,而不是從包含預查的字符之後開始。

(?!pattern)

正向否定預查(negative assert),在任何不匹配pattern的字符串開始處匹配查找字符串。這是一個非獲取匹配,也就是說,該匹配不需要獲取供以後使用。例如"Windows(?!95|98|NT|2000)"能匹配"Windows3.1"中的"Windows",但不能匹配"Windows2000"中的"Windows"。預查不消耗字符,也就是說,在一個匹配發生後,在最後一次匹配之後立即開始下一次匹配的搜索,而不是從包含預查的字符之後開始。

(?<=pattern)反向(look behind)肯定預查,與正向肯定預查類似,只是方向相反。例如,"(?<=95|98|NT|2000)Windows"能匹配"2000Windows"中的"Windows",但不能匹配"3.1Windows"中的"Windows"。
(?<!pattern)反向否定預查,與正向否定預查類似,只是方向相反。例如"(?<!95|98|NT|2000)Windows"能匹配"3.1Windows"中的"Windows",但不能匹配"2000Windows"中的"Windows"。
(?#...) 註釋

\w匹配字母數字及下劃線  '[A-Za-z0-9_]'。
\W匹配非字母數字及下劃線, 等價於 '[^A-Za-z0-9_]'。
\s匹配任意空白字符,等價於 [ \f\n\r\t\v]
\S匹配任意非空字符, [^ \f\n\r\t\v]
\d匹配任意數字,等價於 [0-9].
\D匹配任意非數字
\A匹配字符串開始
\Z匹配字符串結束,如果是存在換行,只匹配到換行前的結束字符串。
\z匹配字符串結束
\G匹配最後匹配完成的位置。
\b匹配一個單詞邊界,也就是指單詞和空格間的位置。例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。
\B匹配非單詞邊界。'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。
\n, \t, 等.匹配一個換行符。匹配一個製表符。等
\1...\9匹配第n個分組的內容。
\10匹配第n個分組的內容,如果它經匹配。否則指的是八進制字符碼的表達式。

\d匹配一個數字字符。等價於 [0-9]。
\D匹配一個非數字字符。等價於 [^0-9]。
\s匹配任何空白字符,包括空格、製表符、換頁符等等。等價於 [ \f\n\r\t\v]。
\S匹配任何非空白字符。等價於 [^ \f\n\r\t\v]。
\w匹配包括下劃線的任何單詞字符。等價於'[A-Za-z0-9_]'。
\W匹配任何非單詞字符。等價於 '[^A-Za-z0-9_]'。

   貪婪匹配與非貪婪匹配

    需要特別指出的是,正則匹配默認是貪婪匹配,也就是匹配儘可能多的字符。舉例如下,匹配出數字後面的0:

>>> re.match(r'^(\d+)(0*)$', '102300').groups()
('102300', '')
    由於\d+採用貪婪匹配,直接把後面的0全部匹配了,結果0*只能匹配空字符串了。
    必須讓\d+採用非貪婪匹配(也就是儘可能少匹配),才能把後面的0匹配出來,加個?就可以讓\d+採用非貪婪匹配: 
>>> re.match(r'^(\d+?)(0*)$', '102300').groups()
('1023', '00')

    同理,?還可以用在其他地方,例如

    *?, +?, ??

         For example, <.*> is matched against '<a> b <c>'  but  <.*?> will match only '<a>'

    {m,n}?

        For example, on the 6-character string 'aaaaaa', a{3,5} will match 5 'a' characters, while a{3,5}? will only match 3 characters.



     


    https://docs.python.org/3/library/re.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章