python學習--正則表達式

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

Python支持的正則表達式元字符和語法:

語法說明實例完整匹配的字符串
一般字符
匹配自身a1b2c3a1b2c3
.匹配任意除換行符'\n'外的字符
l.llol|lpl|lfl
\
轉義字符,使後一個字符改變原來的意思

l\.l

l\\l

l.l

l\l

[...]
對應的位置可以是字符集中任意字符,字符集中的字符可以逐個列出,也可以給出範圍如[abc]或[a-c],第一個字符如果是^則表示取反如[^abc]表示除abc以外的其他字符;所有特殊字符在字符集中都是去其原有特殊意義
a[bcd]e

abe

ace

ade

\d數字:[0-9]
a\dc
a2c
\D
非數字:[^\d]a\Dcaxc
\s
空白字符:[空格,\t\r\n\f\v]a\sca c
\S
非空白字符:[^\s]

\w
單詞字符:[_a-zA-Z0-9]a\wc
axc

\W非單詞字符:[^\w]
a\Wca c
*
匹配前一個字符0或無限次abc*

ab

abcccccc

+
匹配前一個字符1或無限次abc+

abc

abcccccc

?匹配前一個字符0或1次abc?

ab

abc

{m}
匹配前一個字符m次ab{2}cabbc
{m,n}匹配前一個字符m至n次;若省略m,匹配0至n次;若省略n,匹配m至無限次
ab{1,2}c

abc

abbc

*? +? ??

{m,n}?

使* + ? {m,n}變成非貪婪模式

^

匹配字符串開頭

在多行模式中匹配每一行的開頭

^abcabc
$

匹配字符串末尾

在多行模式中匹配每一行的末尾

abc$
abc
\A
僅匹配字符串開頭\Aabcabc
\Z僅匹配字符串末尾abc\Zabc
\b匹配一個單詞邊界,也就是指單詞和空格間的位置。例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。

\B
匹配非單詞邊界。'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。

|

左右表達式任意匹配一個

總是先嚐試匹配左邊表達式,一旦匹配成功則跳過匹配右邊的表達式

abc|def

abc

def

(...)
被括起來的表達式作爲分組

(abc){2}

ab(12|45)c

abcabc

ab45c

(?#...)#後的內容作爲註釋被忽略
ab(?#com..)123ab123

反斜槓

與大多數編程語言相同,正則表達式裏使用"\"作爲轉義字符,這就可能造成反斜槓困擾。假如你需要匹配文本中的字符"\",那麼使用編程語言表示的正則表達式裏將需要4個反斜槓"\\\\":前兩個和後兩個分別用於在編程語言裏轉義成反斜槓,轉換成兩個反斜槓後再在正則表達式裏轉義成一個反斜槓。Python裏的原生字符串很好地解決了這個問題,這個例子中的正則表達式可以使用r"\\"表示。同樣,匹配一個數字的"\\d"可以寫成r"\d"。有了原生字符串,你再也不用擔心是不是漏寫了反斜槓,寫出來的表達式也更直觀。


看一個例子:\d{3}\s+\d{3,8}

我們來從左到右解讀一下:

\d{3}表示匹配3個數字,例如'010';

\s可以匹配一個空格(也包括Tab等空白符),所以\s+表示至少有一個空格,例如匹配' ',' '等;

\d{3,8}表示3-8個數字,例如'1234567'。

綜合起來,上面的正則表達式可以匹配以任意個空格隔開的帶區號的電話號碼。

如果要匹配'010-12345'這樣的號碼呢?由於'-'是特殊字符,在正則表達式中,要用'\'轉義,所以,上面的正則是\d{3}\-\d{3,8}。


進階

要做更精確地匹配,可以用[]表示範圍,比如:

[0-9a-zA-Z\_]可以匹配一個數字、字母或者下劃線;

[0-9a-zA-Z\_]+可以匹配至少由一個數字、字母或者下劃線組成的字符串,比如'a100','0_Z','Py3000'等等;

[a-zA-Z\_][0-9a-zA-Z\_]*可以匹配由字母或下劃線開頭,後接任意個由一個數字、字母或者下劃線組成的字符串,也就是Python合法的變量;

[a-zA-Z\_][0-9a-zA-Z\_]{0, 19}更精確地限制了變量的長度是1-20個字符(前面1個字符+後面最多19個字符)。

A|B可以匹配A或B,所以[P|p]ython可以匹配'Python'或者'python'。

^表示行的開頭,^\d表示必須以數字開頭。

$表示行的結束,\d$表示必須以數字結束。

你可能注意到了,py也可以匹配'python',但是加上^py$就變成了整行匹配,就只能匹配'py'了。


re模塊

re 模塊使 Python 語言擁有全部的正則表達式功能。


re.match

re.match 嘗試從字符串的開始匹配一個模式。

語法:

re.match(pattern, string, flags=0)

參數說明:

pattern    匹配的正則表達式

string     要匹配的字符串。

flags     標誌位,用於控制正則表達式的匹配方式,如:是否區分大小寫,多行匹配等等。


匹配成功re.match方法返回一個匹配的對象,否則返回None。


eg:

import re

sss = re.match(r'^\d{3}\-\d{3,8}$', '010-12345')
print(sss)

<_sre.SRE_Match object; span=(0, 9), match='010-12345'>


可以使用group(num) 或 groups() 匹配對象函數來獲取匹配表達式。

group(num=0)    匹配的整個表達式的字符串,group() 可以一次輸入多個組號,在這種情況下它將返回一個包含那些組所對應值的元組。

groups()    返回一個包含所有小組字符串的元組,從 1 到 所含的小組號。


eg:

line = "Cats are smarter than dogs"
matchObj = re.match(r'(.*) are (.*?) .*', line)
if matchObj:
    print("matchObj.group() : ", matchObj.group())
    print("matchObj.groups() : ", matchObj.groups())
    print("matchObj.group(1) : ", matchObj.group(1))
    print("matchObj.group(2) : ", matchObj.group(2))
else:
    print("No match!!")
    
    
matchObj.group() : Cats are smarter than dogs
matchObj.groups() : ('Cats', 'smarter')
matchObj.group(1) : Cats
matchObj.group(2) : smarter


re.search

語法:

re.search(pattern, string, flags=0)


re.match只匹配字符串的開始,如果字符串開始不符合正則表達式,則匹配失敗,函數返回None;而re.search匹配整個字符串,直到找到一個匹配。

eg:

import re

line = "Cats are smarter than dogs"
matchObj = re.match(r'are', line)
if matchObj:
    print("are ", matchObj.group())
else:
    print("No match!!")

matchObj = re.search(r'are', line)
if matchObj:
    print("are : ", matchObj.group())
else:
    print("No match!!")
    
    
No match!!
are :  are


切分字符串

語法:

split(string[, maxsplit]) | re.split(pattern, string[, maxsplit]):

按照能夠匹配的子串將string分割後返回列表。maxsplit用於指定最大分割次數,不指定將全部分割。 

a = re.split(r'\d+', 'one1two2three3four')
print(a)

['one', 'two', 'three', 'four']

s = re.split(r'\s+', 'a b  c    d w')
print(s)
d = re.split(r'[\s\,\;]+', 'a ,a;b,v g,d    , ;')
print(d)

['a', 'b', 'c', 'd', 'w']
['a', 'a', 'b', 'v', 'g', 'd', '']


findall

findall(string[, pos[, endpos]]) | re.findall(pattern, string[, flags])

搜索string,以列表形式返回全部能匹配的子串。

u = re.findall(r'\d', 'one1two2three3four4')
print(u)

['1', '2', '3', '4']


finditer

finditer(string[, pos[, endpos]]) | re.finditer(pattern, string[, flags])

搜索string,返回一個順序訪問每一個匹配結果(Match對象)的迭代器。

u = re.finditer(r'\d', 'one1two2three3four4')
for i in u:
    print(i.group())
    
1
2
3
4


re.sub用於替換字符串中的匹配項。

語法:

re.sub(pattern, repl, string, max=0)

返回的字符串是在字符串中用 RE 最左邊不重複的匹配來替換。如果模式沒有發現,字符將被沒有改變地返回。

可選參數 count 是模式匹配後替換的最大次數;count 必須是非負整數。缺省值是 0 表示替換所有的匹配

#!/usr/bin/python
import re

phone = "2004-959-559 # This is Phone Number"
num = re.sub(r'#.*', "", phone)
print(num)
nun = re.sub(r'\D', "", num)
print(nun)


2004-959-559 
2004959559


正則表達式非常強大,要講清楚正則的所有內容,可以寫一本厚厚的書了。如果你經常遇到正則表達式的問題,你可能需要一本正則表達式的參考書。


參考:

http://www.cnblogs.com/huxi/archive/2010/07/04/1771073.html

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