本文是關于條件和分組的探索内容,将會在以後新的探索後進行更新,歡迎關注
一、基本符号
分組:()
分組命名:(?P<name> rexp) 将 rexp 比對的字元串作為分組 name
條件:(?(name)Y|N) 當存在分組 name 時,執行 Y 比對,否則執行 N, "|N" 可以省略
二、關于分組命名
先看輸入
caseStr = r'''
1-test fire
2:joker_there
75-just fine
66:all_right
'''
有兩種格式:“數字 -” , “數字:”; “數字 -” 比對帶空格的字元串, “數字:”比對不帶空格的字元串
我們以 (?P<ix1>\b\d+\-.*) 來比對 “數字 -” 這樣的模式,并将組名命名為 ix1,得到的輸出為
['1-', '75-']
表示分别将 '1-' 和 '75-' 命名為 ix1 的組
這裡看不出來分組命名的作用,我們往後面走
三、關于條件
現在,我們有了 ix1 分組,我們用他進行條件判斷,正規表達式為
(?P<ix1>\b\d+\-)(?(ix1)([^\n]+))
後面這段 (?(ix1)([^\n]+)) 表示當比對 ix1 成功後,從 ix1 後面繼續比對得到的結果,于是得到以下結果
[('1-', 'test fire'), ('75-', 'just fine')]
四、應用
那麼現在需要想辦法達到我們的目的了:“數字 -” 比對帶空格的字元串, “數字:”比對不帶空格的字元串
這裡引入另外一個好用的擴充表達式,非捕獲
(?:rexp)
表示比對 rexp 表達式的字元串,但是不傳回比對内容
于是,我們最終的解決思路出來了
mStr = r'''
(?:
(?P<ix1>\b\d+\-)
(?(ix1)([^\n]+))
)
|
(?:
(?P<ix2>\b\d+\:)
(?(ix2)(\w+))
)
'''
傳回結果如下
[('1-', 'test fire', '', ''), ('', '', '2:', 'joker_there'), ('75-', 'just fine', '', ''), ('', '', '66:', 'all_right')]
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiI0NXYFhGd192UvwVe0lmdhJ3ZvwFM38CXlZHbvN3cpR2Lc1TPB10QGtWUCpEMJ9CXsxWam9CXwADNvwVZ6l2c052bm9CXUJDT1wkNhVzLcRnbvZ2Lc1TPR90aWdVYyY0RaZXUYpVd1kmYr50MZV3YyI2cKJDT29GRjBjUIF2LcRHelR3LcJzLctmch1mclRXY39DN2ITNwUzMzIDNygDM3EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
如果沒有非捕獲,傳回的結果如下,會将該組内容傳回
[('1-test fire', '1-', 'test fire', '', '', ''), ('', '', '', '2:joker_there', '2:', 'joker_there'), ('75-just fine', '75-', 'just fine', '', '', ''), ('', '', '', '66:all_right', '66:', 'all_right')]
由于非捕獲不能和分組命名/條件嵌套,是以,這已經是部落客能想到的最好的方式了
如果有讀者能夠消除多餘字元串的傳回(直接通過正規表達式達成),歡迎在評論區留言
五、附源碼
#-*-coding:utf8;-*-
import re
caseStr = r'''
1-test fire
2:joker_there
75-just fine
66:all_right
'''
print caseStr
mStr = r'''
(?:
(?P<ix1>\b\d+\-)
(?(ix1)([^\n]+))
)
|
(?:
(?P<ix2>\b\d+\:)
(?(ix2)(\w+))
)
'''
res = re.findall(mStr, caseStr, re.VERBOSE)
print res
# 2018/06/26 #
發現一個開源的正規表達式工具,叫做Regex101,線上執行,并且有表達式的解釋和常用符号表,還有自己的表達式庫,非常友善