1. 程式人生 > >入門 python 正則化表示式

入門 python 正則化表示式

以前一直沒看,覺得複雜,當下稍微閒了一點,恰小雨,學性大發,記之。

看著很複雜,其實也是用到的時候再找。

1.匯入 re

In [3]: import re

這個是py正則化表示式的庫,我們首先學習re.findall()

python 再help中是這麼解釋的

findall(pattern, string, flags=0)
    Return a list of all non-overlapping matches in the string.

    If one or more capturing groups are present in the pattern, return
    a list of groups; this will be a list of tuples if the pattern
    has more than one group.

    Empty matches are included in the result.

大體意思是如果字串裡有多個匹配結果,就返回一個list。看一個例子。


In [12]: a
Out[12]: 'i love liyunqing, i love python! 123'

In [13]: re.findall("i", a)
Out[13]: ['i', 'i', 'i', 'i']

In [14]: re.findall("love", a)
Out[14]: ['love', 'love']

看了例子是不是有種數學證明題的感覺,就是那種證明題,明明白白,這還需要證明?

先簡單說下這個函式功能,相信大家已經發現,re.findall()返回了字串a中的pattern列表,乍看沒啥nuan用,仔細想想,比如我們可以通過len()統計pattern在a中的數目,做個字元統計啥的。當然,這是findall()函式最直白的顯現。

2.認識元字元

更進一步的,剛剛利用到的是普通字元,現在我們用用新學習的元字元,這裡展示常用的兩個\d and \D。

In [7]: re.findall("\d", a)
Out[7]: ['1', '2', '3']
In [13]: re.findall("\D", a)
Out[13]:
['i',' ','l','o','v','e',' ','l','i','y','u','n','q','i','n','g',',',' ','i',' ','l','o','v','e',' ','p', 'y','t','h','o','n','!']

    # 這塊我改了下排版,結果是對的 

我列了一個常用的元字元,是不是很簡單。

\d 返回數字, [0-9]
\D 返回非數字, [^0-9]
\w 單詞字元(數字+字母)
\W 非單詞字元(空格,\n,\t, #@¥等等)
\s 空白字元(空格,\n,\t, 等,不含#¥%)
. \n之外所有字元

3.正則表示式的一些語法規則

3.0 | 表示並且,不是或!

3.1 [ve] 表示一個字元:v或者e

In [17]: re.findall("[ve]", a)
Out[17]: ['v', 'e', 'v', 'e']

3.2 普通字元的定界+元字元

In [26]: b = "afc acc auc"

In [27]: re.findall("a[cf]c", b)
Out[27]: ['afc', 'acc']

3.3 ^的使用

表示非

In [33]: b
Out[33]: 'afc acc auc'

In [34]: re.findall("a[^cf]c", b)
Out[34]: ['auc']

3.4 -的使用

漢語中“至”的概念,仍舊注意:一個字元

In [36]: a
Out[36]: 'i love liyunqing, i love python!123'

In [37]: re.findall("[1-2]", a)
Out[37]: ['1', '2']

        截至目前為止,我們一直在看針對一個字元的情況,實際需求中,我們找的的肯定不是一個單一的字元。接下來看看多字元的findall。

3.5 多字元

  • [a-z][a-z][a-z]
  • [a-z]{3} # These two methods are equivalent
  • [a-z]{3-6}(貪婪) [a-z]{3-6}?(非貪婪)注意下,有些3個以下的被拋棄了
In [40]: re.findall("[a-z]{3,6}", a)
Out[40]: ['love', 'liyunq', 'ing', 'love', 'python']

In [41]: re.findall("[a-z]{3,6}?", a)
Out[41]: ['lov', 'liy', 'unq', 'ing', 'lov', 'pyt', 'hon']
  • 'py*' 表示前面一個字元,即y,0次到無窮次迴圈都行,eg:p,py,pyyy,pyyyyy都會被檢測出來
  • 'py+' 表示前面一個字元,即y,1次到無窮次迴圈都行, 沒有p了
  • 'py?'表示前面一個字元,即y,0次到1次,如pyyyyyy,則返回py(把多餘的扔掉了)

3.6 邊界匹配問題

^\d{4,8},強制只找最前面

\d{4,8}$,  強制只招最後面

3.7忽略大小寫

r = re.findall('a', a, re.I) # 第三個引數

4.re.sub 函式介紹

re.sub(str1, str2, a, num) # 把str1 代替成str2, 代替num次

p.s. python內建的replace也可以替換,不過是全部替換

最神奇的是,sub可以返回函式!

In [45]: def instead(value):
    ...:     val = value.group()
    ...:     return "little "+val
    ...:

In [46]: re.sub("liyunqing", instead, a)
Out[46]: 'i love little liyunqing, i love python!123'