一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

python正則表達(dá)式

 liluvu 2012-09-22

python正則表達(dá)式  

2012-02-21 13:55:00|  分類: python代碼 |  標(biāo)簽: |字號 訂閱


1. 正則表達(dá)式基礎(chǔ)

1.1. 簡單介紹

正則表達(dá)式并不是Python的一部分。正則表達(dá)式是用于處 理字符串的強(qiáng)大工具,擁有自己獨(dú)特的語法以及一個(gè)獨(dú)立的處理引擎,效率上可能不如str自帶的方法,但功能十分強(qiáng)大。得益于這一點(diǎn),在提供了正則表達(dá)式的 語言里,正則表達(dá)式的語法都是一樣的,區(qū)別只在于不同的編程語言實(shí)現(xiàn)支持的語法數(shù)量不同;但不用擔(dān)心,不被支持的語法通常是不常用的部分。如果已經(jīng)在其他 語言里使用過正則表達(dá)式,只需要簡單看一看就可以上手了。

下圖展示了使用正則表達(dá)式進(jìn)行匹配的流程:
re_simple

正則表達(dá)式的大致匹配過程是:依次拿出表達(dá)式和文本中的字符比較,如果每一個(gè)字符都能匹配,則匹配成功;一旦有匹配不成功的字符則匹配失敗。如果表達(dá)式中有量詞或邊界,這個(gè)過程會稍微有一些不同,但也是很好理解的,看下圖中的示例以及自己多使用幾次就能明白。

下圖列出了Python支持的正則表達(dá)式元字符和語法:  
pyre

1.2. 數(shù)量詞的貪婪模式與非貪婪模式

正 則表達(dá)式通常用于在文本中查找匹配的字符串。Python里數(shù)量詞默認(rèn)是貪婪的(在少數(shù)語言里也可能是默認(rèn)非貪婪),總是嘗試匹配盡可能多的字符;非貪婪 的則相反,總是嘗試匹配盡可能少的字符。例如:正則表達(dá)式"ab*"如果用于查找"abbbc",將找到"abbb"。而如果使用非貪婪的數(shù)量 詞"ab*?",將找到"a"。

1.3. 反斜杠的困擾

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

1.4. 匹配模式

正則表達(dá)式提供了一些可用的匹配模式,比如忽略大小寫、多行匹配等,這部分內(nèi)容將在Pattern類的工廠方法re.compile(pattern[, flags])中一起介紹。

2. re模塊

2.1. 開始使用re

Python通過re模塊提供對正則表達(dá)式的支持。使用re的一般步驟是先將正則表達(dá)式的字符串形式編譯為Pattern實(shí)例,然后使用Pattern實(shí)例處理文本并獲得匹配結(jié)果(一個(gè)Match實(shí)例),最后使用Match實(shí)例獲得信息,進(jìn)行其他的操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# encoding: UTF-8
import re
 
# 將正則表達(dá)式編譯成Pattern對象
pattern = re.compile(r'hello')
 
# 使用Pattern匹配文本,獲得匹配結(jié)果,無法匹配時(shí)將返回None
match = pattern.match('hello world!')
 
if match:
    # 使用Match獲得分組信息
    print match.group()
 
### 輸出 ###
# hello

re.compile(strPattern[, flag]):

這個(gè)方法是Pattern類的工廠方法,用于將字符串形式的正則表達(dá)式編譯為Pattern對象。 第二個(gè)參數(shù)flag是匹配模式,取值可以使用按位或運(yùn)算符'|'表示同時(shí)生效,比如re.I | re.M。另外,你也可以在regex字符串中指定模式,比如re.compile('pattern', re.I | re.M)與re.compile('(?im)pattern')是等價(jià)的。
可選值有:

  • re.I(re.IGNORECASE): 忽略大小寫(括號內(nèi)是完整寫法,下同)
  • M(MULTILINE): 多行模式,改變'^'和'$'的行為(參見上圖)
  • S(DOTALL): 點(diǎn)任意匹配模式,改變'.'的行為
  • L(LOCALE): 使預(yù)定字符類 \w \W \b \B \s \S 取決于當(dāng)前區(qū)域設(shè)定
  • U(UNICODE): 使預(yù)定字符類 \w \W \b \B \s \S \d \D 取決于unicode定義的字符屬性
  • X(VERBOSE): 詳細(xì)模式。這個(gè)模式下正則表達(dá)式可以是多行,忽略空白字符,并可以加入注釋。以下兩個(gè)正則表達(dá)式是等價(jià)的:
1
2
3
4
a = re.compile(r"""\d +  # the integral part
                   \.    # the decimal point
                   \d *  # some fractional digits""", re.X)
b = re.compile(r"\d+\.\d*")

re提供了眾多模塊方法用于完成正則表達(dá)式的功能。這些方法可以使用Pattern實(shí)例的相應(yīng)方法替代,唯一的好處是少寫一行 re.compile()代碼,但同時(shí)也無法復(fù)用編譯后的Pattern對象。這些方法將在Pattern類的實(shí)例方法部分一起介紹。如上面這個(gè)例子可以 簡寫為:

1
2
m = re.match(r'hello', 'hello world!')
print m.group()

re模塊還提供了一個(gè)方法escape(string),用于將string中的正則表達(dá)式元字符如*/+/?等之前加上轉(zhuǎn)義符再返回,在需要大量匹配元字符時(shí)有那么一點(diǎn)用。

2.2. Match

Match對象是一次匹配的結(jié)果,包含了很多關(guān)于此次匹配的信息,可以使用Match提供的可讀屬性或方法來獲取這些信息。

屬性:

  1. string: 匹配時(shí)使用的文本。
  2. re: 匹配時(shí)使用的Pattern對象。
  3. pos: 文本中正則表達(dá)式開始搜索的索引。值與Pattern.match()和Pattern.seach()方法的同名參數(shù)相同。
  4. endpos: 文本中正則表達(dá)式結(jié)束搜索的索引。值與Pattern.match()和Pattern.seach()方法的同名參數(shù)相同。
  5. lastindex: 最后一個(gè)被捕獲的分組在文本中的索引。如果沒有被捕獲的分組,將為None。
  6. lastgroup: 最后一個(gè)被捕獲的分組的別名。如果這個(gè)分組沒有別名或者沒有被捕獲的分組,將為None。

方法:

  1. group([group1, …]):
    獲得一個(gè)或多個(gè)分組截獲的字符串;指定多個(gè)參數(shù)時(shí)將以元組形式返回。group1可以使用編號也可以使用別名;編號0代表整個(gè)匹配的子串;不填寫參數(shù)時(shí),返回group(0);沒有截獲字符串的組返回None;截獲了多次的組返回最后一次截獲的子串。
  2. groups([default]):
    以元組形式返回全部分組截獲的字符串。相當(dāng)于調(diào)用group(1,2,…last)。default表示沒有截獲字符串的組以這個(gè)值替代,默認(rèn)為None。
  3. groupdict([default]):
    返回以有別名的組的別名為鍵、以該組截獲的子串為值的字典,沒有別名的組不包含在內(nèi)。default含義同上。
  4. start([group]):
    返回指定的組截獲的子串在string中的起始索引(子串第一個(gè)字符的索引)。group默認(rèn)值為0。
  5. end([group]):
    返回指定的組截獲的子串在string中的結(jié)束索引(子串最后一個(gè)字符的索引+1)。group默認(rèn)值為0。
  6. span([group]):
    返回(start(group), end(group))。
  7. expand(template):
    將匹配到的分組代入template中然后返回。template中可以使用\id或\g<id>、 \g<name>引用分組,但不能使用編號0。\id與\g<id>是等價(jià)的;但\10將被認(rèn)為是第10個(gè)分組,如果你想表達(dá) \1之后是字符'0',只能使用\g<1>0。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import re
m = re.match(r'(\w+) (\w+)(?P<sign>.*)', 'hello world!')
 
print "m.string:", m.string
print "m.re:", m.re
print "m.pos:", m.pos
print "m.endpos:", m.endpos
print "m.lastindex:", m.lastindex
print "m.lastgroup:", m.lastgroup
 
print "m.group(1,2):", m.group(1, 2)
print "m.groups():", m.groups()
print "m.groupdict():", m.groupdict()
print "m.start(2):", m.start(2)
print "m.end(2):", m.end(2)
print "m.span(2):", m.span(2)
print r"m.expand(r'\2 \1\3'):", m.expand(r'\2 \1\3')
 
### output ###
# m.string: hello world!
# m.re: <_sre.SRE_Pattern object at 0x016E1A38>
# m.pos: 0
# m.endpos: 12
# m.lastindex: 3
# m.lastgroup: sign
# m.group(1,2): ('hello', 'world')
# m.groups(): ('hello', 'world', '!')
# m.groupdict(): {'sign': '!'}
# m.start(2): 6
# m.end(2): 11
# m.span(2): (6, 11)
# m.expand(r'\2 \1\3'): world hello!

2.3. Pattern

Pattern對象是一個(gè)編譯好的正則表達(dá)式,通過Pattern提供的一系列方法可以對文本進(jìn)行匹配查找。

Pattern不能直接實(shí)例化,必須使用re.compile()進(jìn)行構(gòu)造。

Pattern提供了幾個(gè)可讀屬性用于獲取表達(dá)式的相關(guān)信息:

  1. pattern: 編譯時(shí)用的表達(dá)式字符串。
  2. flags: 編譯時(shí)用的匹配模式。數(shù)字形式。
  3. groups: 表達(dá)式中分組的數(shù)量。
  4. groupindex: 以表達(dá)式中有別名的組的別名為鍵、以該組對應(yīng)的編號為值的字典,沒有別名的組不包含在內(nèi)。
1
2
3
4
5
6
7
8
9
10
11
12
13
import re
p = re.compile(r'(\w+) (\w+)(?P<sign>.*)', re.DOTALL)
 
print "p.pattern:", p.pattern
print "p.flags:", p.flags
print "p.groups:", p.groups
print "p.groupindex:", p.groupindex
 
### output ###
# p.pattern: (\w+) (\w+)(?P<sign>.*)
# p.flags: 16
# p.groups: 3
# p.groupindex: {'sign': 3}

實(shí)例方法[ | re模塊方法]:

  1. match(string[, pos[, endpos]]) | re.match(pattern, string[, flags]):
    這個(gè)方法將從string的pos下標(biāo)處起嘗試匹配pattern;如果pattern結(jié)束時(shí)仍可匹配,則返回一個(gè)Match對象;如果匹配過程中pattern無法匹配,或者匹配未結(jié)束就已到達(dá)endpos,則返回None。
    pos和endpos的默認(rèn)值分別為0和len(string);re.match()無法指定這兩個(gè)參數(shù),參數(shù)flags用于編譯pattern時(shí)指定匹配模式。
    注意:這個(gè)方法并不是完全匹配。當(dāng)pattern結(jié)束時(shí)若string還有剩余字符,仍然視為成功。想要完全匹配,可以在表達(dá)式末尾加上邊界匹配符'$'。
    示例參見2.1小節(jié)。
  2. search(string[, pos[, endpos]]) | re.search(pattern, string[, flags]):
    這個(gè)方法用于查找字符串中可以匹配成功的子串。從string的pos下標(biāo)處起嘗試匹配pattern,如果pattern結(jié)束時(shí)仍可匹配,則返回一個(gè)Match對象;若無法匹配,則將pos加1后重新嘗試匹配;直到pos=endpos時(shí)仍無法匹配則返回None。
    pos和endpos的默認(rèn)值分別為0和len(string));re.search()無法指定這兩個(gè)參數(shù),參數(shù)flags用于編譯pattern時(shí)指定匹配模式。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    # encoding: UTF-8
    import re
     
    # 將正則表達(dá)式編譯成Pattern對象
    pattern = re.compile(r'world')
     
    # 使用search()查找匹配的子串,不存在能匹配的子串時(shí)將返回None
    # 這個(gè)例子中使用match()無法成功匹配
    match = pattern.search('hello world!')
     
    if match:
        # 使用Match獲得分組信息
        print match.group()
     
    ### 輸出 ###
    # world
  3. split(string[, maxsplit]) | re.split(pattern, string[, maxsplit]):
    按照能夠匹配的子串將string分割后返回列表。maxsplit用于指定最大分割次數(shù),不指定將全部分割。
    1
    2
    3
    4
    5
    6
    7
    import re
     
    p = re.compile(r'\d+')
    print p.split('one1two2three3four4')
     
    ### output ###
    # ['one', 'two', 'three', 'four', '']
  4. findall(string[, pos[, endpos]]) | re.findall(pattern, string[, flags]):
    搜索string,以列表形式返回全部能匹配的子串。
    1
    2
    3
    4
    5
    6
    7
    import re
     
    p = re.compile(r'\d+')
    print p.findall('one1two2three3four4')
     
    ### output ###
    # ['1', '2', '3', '4']
  5. finditer(string[, pos[, endpos]]) | re.finditer(pattern, string[, flags]):
    搜索string,返回一個(gè)順序訪問每一個(gè)匹配結(jié)果(Match對象)的迭代器。
    1
    2
    3
    4
    5
    6
    7
    8
    import re
     
    p = re.compile(r'\d+')
    for m in p.finditer('one1two2three3four4'):
        print m.group(),
     
    ### output ###
    # 1 2 3 4
  6. sub(repl, string[, count]) | re.sub(pattern, repl, string[, count]):
    使用repl替換string中每一個(gè)匹配的子串后返回替換后的字符串。
    當(dāng)repl是一個(gè)字符串時(shí),可以使用\id或\g<id>、\g<name>引用分組,但不能使用編號0。
    當(dāng)repl是一個(gè)方法時(shí),這個(gè)方法應(yīng)當(dāng)只接受一個(gè)參數(shù)(Match對象),并返回一個(gè)字符串用于替換(返回的字符串中不能再引用分組)。
    count用于指定最多替換次數(shù),不指定時(shí)全部替換。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    import re
     
    p = re.compile(r'(\w+) (\w+)')
    s = 'i say, hello world!'
     
    print p.sub(r'\2 \1', s)
     
    def func(m):
        return m.group(1).title() + ' ' + m.group(2).title()
     
    print p.sub(func, s)
     
    ### output ###
    # say i, world hello!
    # I Say, Hello World!
  7. subn(repl, string[, count]) |re.sub(pattern, repl, string[, count]):
    返回 (sub(repl, string[, count]), 替換次數(shù))。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    import re
     
    p = re.compile(r'(\w+) (\w+)')
    s = 'i say, hello world!'
     
    print p.subn(r'\2 \1', s)
     
    def func(m):
        return m.group(1).title() + ' ' + m.group(2).title()
     
    print p.subn(func, s)
     
    ### output ###
    # ('say i, world hello!', 2)
    # ('I Say, Hello World!', 2)

以上就是Python對于正則表達(dá)式的支持。熟練掌握正則表達(dá)式是每一個(gè)程序員必須具備的技能,這年頭沒有不與字符串打交道的程序了。筆者也處于初級階段,與君共勉,^_^

另外,圖中的特殊構(gòu)造部分沒有舉出例子,用到這些的正則表達(dá)式是具有一定難度的。有興趣可以思考一下,如何匹配不是以abc開頭的單詞,^_^


初學(xué)Python,對Python的文字處理能力有很深的印象,除了str對象自帶的一些方法外,就是正則表達(dá)式這個(gè)強(qiáng)大的模塊了。但是對 于初學(xué)者來說,要用好這個(gè)功能還是有點(diǎn)難度,我花了好長時(shí)間才摸出了點(diǎn)門道。由于我記性不好,很容易就忘事,所以還是寫下來比較好一些,同時(shí)也可以加深印 象,整理思路。

由于我是初學(xué),所以肯定會有些錯(cuò)誤,還望高手不吝賜教,指出我的錯(cuò)誤。

1 Python正則式的基本用法

Python的正則表達(dá)式的模塊是 ‘re’,它的基本語法規(guī)則就是指定一個(gè)字符序列,比如你要在一個(gè)字符串s=’123abc456’ 中查找字符串 ’abc’,只要這樣寫:

>>> import re

>>> s='123abc456eabc789'

>>> re.findall(r’abc’,s)

結(jié)果就是:

['abc', 'abc']


這里用到的函數(shù) ”findall(rule , target [,flag] )” 是個(gè)比較直觀的函數(shù),就是在目標(biāo)字符串中查找符合規(guī)則的字符串。第一個(gè)參數(shù)是規(guī)則,第二個(gè)參數(shù)是目標(biāo)字符串,后面還可以跟一個(gè)規(guī)則選項(xiàng)(選項(xiàng)功能將在 compile函數(shù)的說明中詳細(xì)說明)。返回結(jié)果結(jié)果是一個(gè)列表,中間存放的是符合規(guī)則的字符串。如果沒有符合規(guī)則的字符串被找到,就返回一個(gè)空列表。

為什么要用r’ ..‘字符串(raw字符串)? 由于正則式的規(guī)則也是由一個(gè)字符串定義的,而在正則式中大量使用轉(zhuǎn)義字符’\’,如果不用raw字符串,則在需要寫一個(gè)’\’的地方,你必須得寫成’ \\’,那么在要從目標(biāo)字符串中匹配一個(gè)’\’的時(shí)候,你就得寫上4個(gè)’\’成為’\\\\’!這當(dāng)然很麻煩,也不直觀,所以一般都使用r’’來定義規(guī)則 字符串。當(dāng)然,某些情況下,可能不用raw字符串比較好。

以上是個(gè)最簡單的例子。當(dāng)然實(shí)際中這么簡單的用法幾乎沒有意義。為了實(shí)現(xiàn)復(fù)雜的規(guī)則查找,re規(guī)定了若干語法規(guī)則。它們分為這么幾類:

功能字符 :    ‘.’ ‘*’ ‘+’ ‘|’ ‘?’ ‘^’ ‘$’ ‘\’ 等,它們有特殊的功能含義。特別是’\’字符,它是轉(zhuǎn)義引導(dǎo)符號,跟在它后面的字符一般有特殊的含義。

規(guī)則分界符: ‘[‘ ‘]’ ‘(’ ‘)’ ‘{‘ ‘}’ 等,也就是幾種括號了。

預(yù)定義轉(zhuǎn)義字符集: “\d”  “\w” “\s” 等等,它們是以字符’\’開頭,后面接一個(gè)特定字符的形式,用來指示一個(gè)預(yù)定義好的含義。

其它特殊功能字符: ’#’ ‘!’ ‘:’ ‘-‘等,它們只在特定的情況下表示特殊的含義,比如(?# …)就表示一個(gè)注釋,里面的內(nèi)容會被忽略。

下面來一個(gè)一個(gè)的說明這些規(guī)則的含義,不過說明的順序并不是按照上面的順序來的,而是我認(rèn)為由淺入深,由基本到復(fù)雜的順序來編排的。同時(shí)為了直觀, 在說明的過程中盡量多舉些例子以方便理解。


1.1 基本規(guī)則

‘[‘  ‘]’ 字符集合設(shè)定符

首先說明一下字符集合設(shè)定的方法。由一對方括號括起來的字符,表明一個(gè)字符集合,能夠匹配包含在其中的任意一個(gè)字符。比如 [abc123],表明字符’a’ ‘b’ ‘c’ ‘1’ ‘2’ ‘3’都符合它的要求。可以被匹配。

在’[‘ ‘]’中還可以通過 ’-‘ 減號來指定一個(gè)字符集合的范圍,比如可以用[a-zA-Z]來指定所以英文字母的大小寫,因?yàn)橛⑽淖帜甘前凑諒男〉酱蟮捻樞騺砼诺摹D悴豢梢园汛笮〉捻樞? 顛倒了,比如寫成[z-a]就不對了。

如果在’[‘ ‘]’里面的開頭寫一個(gè) ‘^’ 號,則表示取非,即在括號里的字符都不匹配。如[^a-zA-Z]表明不匹配所有英文字母。但是如果 ‘^’不在開頭,則它就不再是表示取非,而表示其本身,如[a-z^A-Z]表明匹配所有的英文字母和字符’^’。

‘|’    或規(guī)則

將兩個(gè)規(guī)則并列起來,以‘|’連接,表示只要滿足其中之一就可以匹配。比如

[a-zA-Z]|[0-9] 表示滿足數(shù)字或字母就可以匹配,這個(gè)規(guī)則等價(jià)于 [a-zA-Z0-9]

注意:關(guān)于’|’要注意兩點(diǎn):


第一,           它在’[‘ ‘]’之中不再表示或,而表示他本身的字符。如果要在’[‘ ‘]’外面表示一個(gè)’|’字符,必須用反斜杠引導(dǎo),即 ’\|’ ;

第二,           它的有效范圍是它兩邊的整條規(guī)則,比如‘dog|cat’匹配的是‘dog’和’cat’,而不是’g’和’c’。如果想限定它的有效范圍,必需使用一個(gè) 無捕獲組 ‘(?: )’包起來。比如要匹配 ‘I have a dog’或’I have a cat’,需要寫成r’I have a (?:dog|cat)’ ,而不能寫成 r’I have a dog|cat’

>>> s = ‘I have a dog , I have a cat’

>>> re.findall( r’I have a (?:dog|cat)’ , s )

['I have a dog', 'I have a cat']                #正如我們所要的

下面再看看不用無捕獲組會是什么后果:

>>> re.findall( r’I have a dog|cat’ , s )

['I have a dog', 'cat']                                   #它將’I have a dog’ 和’cat’當(dāng)成兩個(gè)規(guī)則了

至于無捕獲組的使用,后面將仔細(xì)說明。這里先跳過。


‘.’    匹配所有字符

匹配除換行符’\n’外的所有字符。如果使用了’S’選項(xiàng),匹配包括’\n’的所有字符。

       例:

       >>> s=’123 \n456 \n789’

       >>> findall(r‘.+’,s)

       ['123', '456', '789']

       >>> re.findall(r‘.+’ , s , re.S)

       ['123\n456\n789']

‘^’和’$’ 匹配字符串開頭和結(jié)尾

注意’^’不能在‘[ ]’中,否則含意就發(fā)生變化,具體請看上面的’[‘ ‘]’說明。 在多行模式下,它們可以匹配每一行的行首和行尾。具體請看后面compile函數(shù)說明的’M’選項(xiàng)部分

‘\d’ 匹配數(shù)字


這是一個(gè)以’\’開頭的轉(zhuǎn)義字符,’\d’表示匹配一個(gè)數(shù)字,即等價(jià)于[0-9]

‘\D’ 匹配非數(shù)字

這個(gè)是上面的反集,即匹配一個(gè)非數(shù)字的字符,等價(jià)于[^0-9]。注意它們的大小寫。下面我們還將看到Python的正則規(guī)則中很多轉(zhuǎn)義字符的大小 寫形式,代表互補(bǔ)的關(guān)系。這樣很好記。

‘\w’ 匹配字母和數(shù)字

匹配所有的英文字母和數(shù)字,即等價(jià)于[a-zA-Z0-9]。

‘\W’ 匹配非英文字母和數(shù)字

即’\w’的補(bǔ)集,等價(jià)于[^a-zA-Z0-9]。

‘\s’ 匹配間隔符

即匹配空格符、制表符、回車符等表示分隔意義的字符,它等價(jià)于[ \t\r\n\f\v]。(注意最前面有個(gè)空格)

‘\S’ 匹配非間隔符

即間隔符的補(bǔ)集,等價(jià)于[^ \t\r\n\f\v]


‘\A’ 匹配字符串開頭

匹配字符串的開頭。它和’^’的區(qū)別是,’\A’只匹配整個(gè)字符串的開頭,即使在’M’模式下,它也不會匹配其它行的很首。

‘\Z’ 匹配字符串結(jié)尾

匹配字符串的結(jié)尾。它和’$’的區(qū)別是,’\Z’只匹配整個(gè)字符串的結(jié)尾,即使在’M’模式下,它也不會匹配其它各行的行尾。

例:

>>> s= '12 34\n56 78\n90'

>>> re.findall( r'^\d+' , s , re.M )          #匹配位于行首的數(shù)字

['12', '56', '90']

>>> re.findall( r’\A\d+’, s , re.M )        #匹配位于字符串開頭的數(shù)字

['12']

>>> re.findall( r'\d+$' , s , re.M )          #匹配位于行尾的數(shù)字

['34', '78', '90']

>>> re.findall( r’\d+\Z’ , s , re.M )        #匹配位于字符串尾的數(shù)字

['90']

‘\b’ 匹配單詞邊界

它匹配一個(gè)單詞的邊界,比如空格等,不過它是一個(gè)‘0’長度字符,它匹配完的字符串不會包括那個(gè)分界的字符。而如果用’\s’來匹配的話,則匹配出 的字符串中會包含那個(gè)分界符。

例:

>>> s =  'abc abcde bc bcd'

>>> re.findall( r’\bbc\b’ , s )         #匹配一個(gè)單獨(dú)的單詞 ‘bc’ ,而當(dāng)它是其它單詞的一部分的時(shí)候不匹配

['bc']                                           #只找到了那個(gè)單獨(dú)的’bc’

>>> re.findall( r’\sbc\s’ , s )          #匹配一個(gè)單獨(dú)的單詞 ‘bc’

[' bc ']                                         #只找到那個(gè)單獨(dú)的’bc’,不過注意前后有兩個(gè)空格,可能有點(diǎn)看不清楚

‘\B’ 匹配非邊界

和’\b’相反,它只匹配非邊界的字符。它同樣是個(gè)0長度字符。

接上例:

>>> re.findall( r’\Bbc\w+’ , s )     #匹配包含’bc’但不以’bc’為開頭的單詞

['bcde']                                       #成功匹配了’abcde’中的’bcde’,而沒有匹配’bcd’

‘(?:)’ 無捕獲組

當(dāng)你要將一部分規(guī)則作為一個(gè)整體對它進(jìn)行某些操作,比如指定其重復(fù)次數(shù)時(shí),你需要將這部分規(guī)則用’(?:’ ‘)’把它包圍起來,而不能僅僅只用一對括號,那樣將得到絕對出人意料的結(jié)果。

例:匹配字符串中重復(fù)的’ab’

>>> s=’ababab abbabb aabaab’

>>> re.findall( r’\b(?:ab)+\b’ , s )

['ababab']

如果僅使用一對括號,看看會是什么結(jié)果:

>>> re.findall( r’\b(ab)+\b’ , s )

['ab']

這是因?yàn)槿绻皇褂靡粚ㄌ?,那么這就成為了一個(gè)組(group)。組的使用比較復(fù)雜,將在后面詳細(xì)講解。

‘(?# )’ 注釋

Python允許你在正則表達(dá)式中寫入注釋,在’(?#’ ‘)’之間的內(nèi)容將被忽略。

(?iLmsux) 編譯選項(xiàng)指定

Python的正則式可以指定一些選項(xiàng),這個(gè)選項(xiàng)可以寫在findall或compile的參數(shù)中,也可以寫在正則式里,成為正則式的一部分。這在 某些情況下會便利一些。具體的選項(xiàng)含義請看后面的compile函數(shù)的說明。

此處編譯選項(xiàng)’i’ 等價(jià)于IGNORECASE ,L 等價(jià)于 LOCAL ,m 等價(jià)于 MULTILINE ,s 等價(jià)于 DOTALL ,u 等價(jià)于 UNICODE , x 等價(jià)于 VERBOSE 。

請注意它們的大小寫。在使用時(shí)可以只指定一部分,比如只指定忽略大小寫,可寫為 ‘(?i)’,要同時(shí)忽略大小寫并使用多行模式,可以寫為 ‘(?im)’。

另外要注意選項(xiàng)的有效范圍是整條規(guī)則,即寫在規(guī)則的任何地方,選項(xiàng)都會對全部整條正則式有效。

1.2 重復(fù)

正則式需要匹配不定長的字符串,那就一定需要表示重復(fù)的指示符。Python的正則式表示重復(fù)的功能很豐富靈活。重復(fù)規(guī)則的一般的形式是在一條字符 規(guī)則后面緊跟一個(gè)表示重復(fù)次數(shù)的規(guī)則,已表明需要重復(fù)前面的規(guī)則一定的次數(shù)。重復(fù)規(guī)則有:

‘*’   0或多次匹配

表示匹配前面的規(guī)則0次或多次。

‘+’   1次或多次匹配

表示匹配前面的規(guī)則至少1次,可以多次匹配

例:匹配以下字符串中的前一部分是字母,后一部分是數(shù)字或沒有的變量名字

>>> s = ‘ aaa bbb111 cc22cc 33dd ‘

>>> re.findall( r’\b[a-z]+\d*\b’ , s )             #必須至少1個(gè)字母開頭,以連續(xù)數(shù)字結(jié)尾或沒有數(shù)字

['aaa', 'bbb111']

注意上例中規(guī)則前后加了表示單詞邊界的’\b’指示符,如果不加的話結(jié)果就會變成:

>>> re.findall( r’[a-z]+\d*’ , s )

['aaa', 'bbb111', 'cc22', 'cc', 'dd']    #把單詞給拆開了

大多數(shù)情況下這不是我們期望的結(jié)果。

‘?’   0或1次匹配

只匹配前面的規(guī)則0次或1次。

例,匹配一個(gè)數(shù)字,這個(gè)數(shù)字可以是一個(gè)整數(shù),也可以是一個(gè)科學(xué)計(jì)數(shù)法記錄的數(shù)字,比如123和10e3都是正確的數(shù)字。

>>> s = ‘ 123 10e3 20e4e4 30ee5 ‘

>>> re.findall( r’ \b\d+[eE]?\d*\b’ , s )

['123', '10e3']

它正確匹配了123和10e3,正是我們期望的。注意前后的’\b’的使用,否則將得到不期望的結(jié)果。

    本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    欧美一级日韩中文字幕| 十八禁日本一区二区三区| 日韩不卡一区二区视频| 亚洲熟妇av一区二区三区色堂| 老鸭窝精彩从这里蔓延| 亚洲国产日韩欧美三级| 久久黄片免费播放大全| 麻豆91成人国产在线观看| 亚洲伊人久久精品国产| 99久久精品午夜一区| 国产精品久久香蕉国产线| 国产又粗又深又猛又爽又黄| 不卡一区二区在线视频| 日本欧美一区二区三区高清| 欧美乱码精品一区二区三| 日韩和欧美的一区二区三区| 久久大香蕉一区二区三区| 日本二区三区在线播放| 日韩人妻欧美一区二区久久| 欧美日韩国产福利在线观看| 日本免费一本一二区三区| 91欧美激情在线视频| 九九热九九热九九热九九热 | 不卡在线播放一区二区三区| 亚洲精品伦理熟女国产一区二区| 99视频精品免费视频| 亚洲一级在线免费观看| 91亚洲国产—区=区a| 亚洲欧美日韩网友自拍| 国产精品久久熟女吞精| 国产av熟女一区二区三区蜜桃| 九九热视频网在线观看| 日本女优一色一伦一区二区三区| 国产精品丝袜一二三区| 在线亚洲成人中文字幕高清| 91超频在线视频中文字幕| 亚洲婷婷开心色四房播播| 精品一区二区三区乱码中文| 国产偷拍盗摄一区二区| 国产目拍亚洲精品区一区| 91麻豆视频国产一区二区|