Python的正则表达式和re模块
1. 正則表達式
1.1 用處
正則表達式就是記錄文本規則的代碼
這句話我覺得概括的很精煉.
1.2 元字符
正則表達式里有一些元字符, 他們代表的是很多意思, 有某種特征的集合呀, 不包括某種字符的集合呀.
1.2.1 匹配字符種類的元字符
以下探討的都是代表一個字符的元字符.
. : 就是英文字符的句號 . , 匹配除了換行符以外的任意字符。
\s: 匹配任意的空白符,包括空格,制表符(Tab),換行符,中文全角空格等.
\S: 匹配任意不是空白符的字符.
\w: 匹配字母[a-z], [A-Z] 或數字[0-9] 或下劃線_ 或漢字等.
\W: 匹配任意不是字母,數字,下劃線,漢字的字符.
\d: 是匹配一位數字從0到9, 任意一個數字就行。
\D: 匹配任意非數字的字符
\b: 并不匹配這些單詞分隔字符中的任何一個,它只匹配一個位置. 這個位置和后一個字符或者前一個字符的類型不一樣.
比如: \b\w, 這個\b就是匹配不是\w的字符, 并且不會匹配到這個字符; 如果是\b. , 就是匹配不是. 的字符. 就近匹配,比如\bAB 匹配A,AB\b 匹配B
\B: 就是上面反過來, 說不清, 舉例來看: ‘aabbc’ 中 ‘\Ba’ 匹配的是第二個a, 因為\B代表跟后面的字符類型一樣的字符, 但是不要這個\B代表的字符.
[ ]:從中挑一個字符, 注意是一個字符, 例如[fuck]就是從f, u, c, k 四個字符中挑選一個, 還有[0-9]從0到9選一個, 還有[a-d]或者[E-G], 從a, b, c, d 或者E, F, G中選一個.
| : 從前或者后, 選出取個來, 是或的意思. 例如: ‘abc|de’ 的符合匹配對象是’abc’ 或者’de’, 而不是’abc’ 或’abde’. 一定要注意.
[^ ]: 取反^配合[ ]使用, 就是[ ]內的字符以外的字符都可以, 例如: [^\d]匹配除了數字以外的任意字符, [^aeiou]匹配除了aeiou這幾個字母以外的任意字符.
\A: 代表后面這個字符必須在字符串開頭. 例如: ‘aba’ 用’\Aa’ 來匹配, 能匹配到第一個a, 不能匹配到第二個a; 如果用’\Ab’ 來匹配, 匹配不到.
^: 用來表示, ^后面這個字符, 必須是一行的開始, mutilline模式下, 會按行分隔符分隔成很多行, 所以會有很多行首, 在默認模式和singleline模式下, 就是一個長的字符串, 所以只有一個行首
$: $前面的這個字符, 必須是行尾, 規律同上.
一共11種.
1.2.2 控制字符數量的元字符
配合上面代表字符種類的元字符使用, 接在字符的后面, 可以代表字符重復多少次. 注意, 他們只控制前面一個字符的數量.
貪婪地匹配:
因為能匹配到的數量不確定, 所以就盡可能多的匹配, 比如’@bbb@bbb@’ 中, 用’@.+@’來匹配, 結果是’@bbb@bbb@’ .
* :前邊的內容可以連續重復使用任意次以使整個表達式得到匹配。.* 連在一起, 在singleline模式下就意味著任意數量的不包含換行的字符。
+: 重復一次以上
?: 重復零次或一次
{n}: 重復n次
{n,}: 重復n次或更多次, {1,} 相當于+ .
{n,m}: 重復n到m次, {0,1} 相當于? . 例如: 0\d{2}-\d{8}。這里\d后面的{2}({8})的意思是前面\d必須連續重復匹配2次(8次), 用于匹配0xx-xxxxxxxx這樣的字符串.
有時候, 我們需要這些元字符的本意, 比如我就想查找?, 這是需要用\來取消這些字符的特殊意義, \?就表示?。所以要查找\本身,要用\.
正則表達式里的分枝條件指的是有幾種規則,只要滿足這些規則中的任意一種,都會被當成匹配,因此我們要使用 | 把這些規則分開。
懶惰地匹配:
還是上面那個例子, 如果只想要’@bbb@bbb@’ 中, 符合條件的第一個字符串, 就可以用’@.+?@’來匹配, 結果是’@bbb@’, 是左邊的那個 .
*?: 重復任意次,但盡可能少重復
+?: 重復1次或更多次,但盡可能少重復
??: 重復0次或1次,但盡可能少重復
{n,m}?: 重復n到m次,但盡可能少重復
{n,}?: 重復n次以上,但盡可能少重復
1.2.3 匹配重復出現某一組成部分的字符串
有的時候, 我們要用到前面匹配的字符串, 但是我們是在寫正則表達式, 不知道會匹配到什么, 可以用分組來解決.
(exp): 匹配exp, 并捕獲文本到自動命名的組里. 然后用這些組的編號來調用, 最左邊定的分組編號是1, 以此類推. 例如’(\w).*?\1’ 可以匹配, ‘afuckafuckf’ 中的’afucka’ 和’fuckf’ 這樣的字符串, 注意, 因為還沒有匹配, 所以分組捕獲的實際字符串是什么沒有確定, 只有開始具體的字符串后, 才能知道分組匹配的是什么.
(?<>exp): 匹配exp, 在<>里面可以寫分組的名字,但是調用分組的時候還是要寫編號, 估計這個分組只是一個注釋作用吧, 也可以寫成(?’name’exp). 此處要吐槽CSDN這格式是個什么玩意.
(?:exp): 有時候要用()來改變匹配的優先級, 就要寫成(?:)不然優先級是改變了, 但是把不想分組的內容分了組, 給了編號, 可能會有不便.
分組0對應整個正則表達式.
實際上組號分配過程是要從左向右掃描兩遍的:第一遍只給未命名組分配,第二遍只給命名組分配, 因此所有命名組的組號都大于未命名的組.
零寬斷言
斷言用來聲明一個應該為真的事實。正則表達式中只有當斷言為真時才會繼續進行匹配。
正向:
(?=exp): 匹配以exp結尾的字符串, 不包快這個exp, 例如’\w(?=\d)’ 代表一個\w字符, 這個字符必須以數字結尾, 如果用來匹配’1a2bcde’, 匹配到的是a.
(?<=exp): 匹配以exp開頭的字符串. 上面的例子:’(?<=\d)\w’ 匹配到的是a和b
負向:
(?!exp): 匹配不能以exp結尾的字符串.
(?<!exp): 匹配不能以exp開頭的字符串.
注釋
(?#comment) 這種類型的分組不對正則表達式的處理產生任何影響,用于提供注釋讓人閱讀
1.3 一般的軟件模式
這些模式用于不同的需求. 以RegExTexter.exe為例, 默認模式, 就是. 不能代表換行符的單行模式.
IgnoreCase(忽略大小寫)模式:
匹配時不區分大小寫。
Multiline(多行模式):
根據換行符, 把文本換行, 但是不去掉換行符.
主要作用就是, 變出了很多個行首和行尾.
Singleline(單行模式)
更改.的含義,使它與每一個字符匹配(包括換行符\n)。
2. re模塊
python中有適用于正則表達式的模塊, 就是re模塊.
在python中有兩種使用正則表達式的方法, 第一種是, 用re下的方法直接匹配, 但是需要以字符串的形式輸入正則表達式; 第二種是, 把正則表達式生成一個regex對象, 然后調用這個對象的方法來匹配.
匹配的返回值可以是str或者是match對象, match對象里面包含了匹配到的字符串的內容和索引.
python也提供了幾種不同的模式來匹配:
re.I
re.IGNORECASE #這個模式是忽略字母的大小寫
re.M
re.MULTILINE #多行模式
re.S
re.DOTALL #這個模式下, .也可以代表換行符
re.X
re.VERBOSE #忽略大小寫模式, 可以讓正則表達式看起來更好看, 我覺得還是別用吧
2.1 直接匹配:
re.match(pattern, string, flags=0)
pattern是正則表達式, string是要匹配的文本, flags是選擇用什么模式來匹配.
就是錨定開頭, 這個正則表達式, 如果不再開頭的話, 就算沒找到
匹配到了, 返回match對象. 沒匹配到, 什么都不返回.
import re a = re.match('\d', '123r123')print(a) (<_sre.SRE_Match object; span=(0, 1), match='1'>)re.search(pattern, string, flags=0)
同樣值匹配一次, 但是沒有錨定開頭
re.fullmatch(pattern, string, flags=0)
看整個字符串是否符合正則表達式
re.findall(pattern, string, flags=0)
從整個字符串開始匹配, 找到結果, 把結果以列表的形式返回.
re.finditer(pattern, string, flags=0)
也是從整個字符串里找
返回一個迭代器, 每次迭代出符合條件的match對象
re.sub(pattern, repl, string, count=0, flags=0)
在string里找到符合pattern的字符串, 把它替換成repl,
count指定替換次數, 默認是0, 就是全局替換,
返回的是替換好的字符串.
re.subn(pattern, repl, string, count=0, flags=0)
跟上面那個用法一毛一樣, 區別就是, 這個會返回一個二元組, 第一個元素是替換好的string, 第二個元素是替換次數.
(?<=<(\w+)>).*(?=<\/\1>)匹配不包含屬性的簡單HTML標簽內里的內容。
re.split(pattern, string, maxsplit=0, flags=0)
把string中符合pattern的字符串都切掉, 和str.split()效果差不多, maxsplit是指定切割次數的.
2.2 生成regex對象再匹配
re.compile(pattern, flags=0)
用標識符來接收, 注意, 這個對象是要在匹配之前設置好匹配模式的.
然后regex的方法和re的方法差不多, 后面只放目標string就行了, 但是可以指定開始和結束的位置:
regex.match(string[, pos[, endpos]])
regex.search(string[, pos[, endpos]])
regex.fullmatch(string[, pos[, endpos]])
regex.findall(string[, pos[, endpos]])
regex.finditer(string[, pos[, endpos]])
regex.sub(repl, string, count=0)
regex.subn(repl, string, count=0)
regex.split(string, maxsplit=0)
3. match對象
match.group([group1, …])
后面括號寫分組的編號, 可以得到字符串形式的分組
match.groups(default=None)
可以把所有的分組放在一個元組里面返回來
match.groupdict(default=None)
如果給分組命名了的話, 注意python中分組要用(?P<’name’>)來命名, 這個方法可以返回一個字典.
總結
以上是生活随笔為你收集整理的Python的正则表达式和re模块的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 蓝牙耳机按键事件linux,【记录】An
- 下一篇: ZigBee智能节水灌溉系统