7.2. re — Regular expression operations正則表達式 p...

文中翻譯有些不到位的地方請看原文http://docs.python.org/library/re.htmlhtml

另推薦有關python re的文檔http://docs.python.org/howto/regexpython

中文翻譯可參加http://www.cnblogs.com/ltang/archive/2011/07/31/2122914.html  git



本模塊提供了那些在Perl中可找到的類似的匹配操做。被搜索的patternsstrings能夠是Unicode性字符串或8位字符串。正則表達式

    正則表達式使用了反斜線'\'字符來指示特別的形式或容許在不使用它們特別含義的狀況下使用這寫特殊字符。這樣會有問題,好比,爲了匹配字面上的反斜線'\'pattern可能會是'\\\\',由於正則表達式必須是\\, 而且每個反斜線在正常的python字面字符串必須被表示爲\\express

    爲此的解決方案是使用pythonraw string觀念;在前綴'r'的反斜線不在具備特別含義因此r"\n"是包含'\''n'2個字符,而"\n"自己是一個換行符是一個字符。一般,在Python代碼中的patterns被表示爲raw string    明白大部分正則表示操做可在模塊級函數和RegexObject方法下完成是很重要的。這些函數不須要你首先編譯一個regex對象,但也失去了一些fine-tuning參數,因此是捷徑。--參見  Mastering Regular Expressions 一書緩存

7.2.1. Regular Expression Syntax數據結構

    正則表達式(RE)明確了a set of strings that matches it;本模塊中的函數讓你檢查一個特別的string是否匹配一個給出的re正則表達式(或給出的re是否匹配特別的stringless

    多個正則表達式可聯合成新的正則表達式;若是AB都是RE,則AB也是RE,通常來講,若是字符串P匹配A而且另外一個字符串Q匹配B,則PQ將匹配ABThis holds unless A or B contain low precedence operations; boundary conditions between A and B; or have numbered group references.所以複雜的表達式可有小的簡單表達式構成。dom

    正則表達式可包含特殊和普通字符。大部分普通字符好比'A','B','C'是最簡單的正則表達式;他們只是匹配他們本身 。可聯合起來,因此last匹配'last'(剩下將介紹特別類型)函數

    一些像'|' , '('的特殊字符。特殊字符或者表明了普通字符類,或者影響着他們周圍的正則表達式是如何別解釋的。pattern不要包含null字節,但可以使用\number中的null 字節好比'\x00'

    特殊字符:

'.'  :默認時匹配除換行符外的任意字符,若是明確了DOTALL標記,這匹配包含換行符在內的全部字符。

'^' :匹配string的開始,在multiline模式下在每一行就匹配

'*' :使前面的RE匹配0次或屢次。因此 ab*將匹配'a' , 'ab' , 'a'並後跟任意多個'b'

'?' : 使前面的RE匹配0次或1次。因此ab?將匹配'a' 'ab'

*?   +?   ?? : '*' ,'+' ,'?'都是貪心的;他們能匹配多少就匹配多少。有時這種行爲是不但願的;若是RE <.*>匹配'<H1>title</H1>'時將匹配整個字符串而不是咱們想要的'<H1>'.因此,後加'?'將使非貪心或minimal模式;可以少匹配多少就匹配多少,因此,   .*?將匹配'<H1>' .

{m} :前面的RE匹配m次;好比a{6}將明確匹配6'a'字符,而不是5次。

{m,n} :前面的RE匹配mn次,在mn的範圍內能匹配多少就匹配多少。好比 a{3,5}將匹配從35次的'a'。省略m時說明從0次開始匹配,省略n時說明了上界爲無窮屢次的匹配。好比,a{4,}b匹配aaab100'a'再後接'b',但不是'aaab'.

{m,n}? :前面的RE匹配mn次,在mn的範圍內能少匹配多少就匹配多少。因此是非貪心的,若是string'aaaaaa'a{3,5}將匹配5'a' a{3,5}?將匹配只3'a'

'\' :或者轉義(escapes)特殊字符(即容許你匹配像'*','?'的特殊字符),或signals 一個特殊的字符串:

若是你不使用raw string來表示pattern,記得python也在string literals中將反斜線'\'用做轉義字符;若是python語法分析器不認識轉義字符,則反斜線和接下來的字符會被包含在最終結果的string中,可是,若是python識別了最終序列,則反斜線應重複2次。複雜斌難以理解,因此強烈推薦使用raw strings

[] :明確字符集

1.單獨列出來的字符 [amk]將匹配'a' 'm' 'k'

2. 字符範圍 [a-z]小寫字母  [0-5][0-9]兩位數字00-59   [0-9A-Fa-f]匹配16進制位,若是'-'被轉義([a\-z])或被放在開頭或結尾([a-])見匹配'-'

3. []中特殊字符失去了其特殊的含義,好比[(+*)]將匹配字面上的'(' '+'  '*' ')'

4. \w \S的字符類也可放在[]中,即便匹配的字符依賴於LOCALEUNICODE模式是否有效

5. 匹配不在[]中的字符,若是字符集中的第一個字符是'^',則匹配字符集外的任意字符。好比[^5]將匹配除了5之外的任意字符,[^^]將匹配除了'^'外的任意字符。'^'若是不出如今字符集的第一個字符則沒有特殊的含義。

6. 爲了在集合中匹配']',前加反斜線或放在集合開頭。好比 [()[\]{}][]()[{}]都匹配圓括號

 

'|' :A|B (其中AB但是任意的RE)創造了一個將匹配A或者B的正則表達式。任意數量的RE可由'|'方式分隔。此中方式也可在group中出現(下面)。當目標字符串被scanned時,由'|'分隔的RE從左到右一個一個被試。但有一個徹底匹配時,此分支被接受。意味着一旦A匹配了,則B不會被test一遍,即便B可能會有一個更長的匹配。換句話說,'|'是非貪心的。爲了匹配字母上的literal '|' 使用\|或放入[]中爲[|]

(...) :只是將RE放入此中,以便後面引用:\number。爲了匹配字面上的''( ')'使用\(\)或在字符類中:[(] [)]

(?...) :

(?iLnsux): 

(?:...): 非捕獲版的RE。匹配的字串沒法在後面須要時被引用

(?P<name>...): (...)只是匹配後可由group名來引用。好比若是pattern(?P<id>[a-zA-Z_]\w*),則之後可用m.group('id')m.end('id')方式引用,

(?P=name): group名爲nameRE

(?#...): 註釋;圓括號中的註釋被忽略

(?=...): 若是...匹配下面的時此才匹配,但不消耗任意的string。被叫作lookahead assertion。好比,Isaac(?=Asimov)只在後接'Asimov時才'將匹配'Isaac'

(?!...): 若是...不匹配下面的時此才匹配,好比 Isaac(?!Asimov)將匹配'Isaac'只在不後接'Asimov'

(?<=...):前接...時才匹配。(?<=abc)def將在abcdef中發現一個匹配,...只能是固定長度的pattern,好比 abca|b能夠,但a*a{3,4}不行。

>>> import re >>> m = re.search('(?<=abc)def', 'abcdef') >>> m.group(0) 'def'

此例找前跟連字號的一個word:

>>> m = re.search('(?<=-)\w+', 'spam-egg') >>> m.group(0) 'egg'

(?<!...): 若是不前接...時此才匹配。同上,...比是固定長度。

(?(id/name)yes-pattern|no-pattern): 若是爲id或名爲namegroup存在時纔去匹配yes-pattern,反之,匹配no-patternno-pattern是可選的也就可省略。好比,(<)?(\w+@\w+(?:\. \w+)+)(?(1)>)是可poor的郵件匹配pattern,將匹配'<user@host.com>''user@host.com'但不會匹配'<user@host.com' .

 

New in version 2.4.

\number:匹配編號爲numberRE

    group1開始編號。好比(.+) \1匹配'the the ' '55 55',但不是'the end' (注意空格).編號只能從099.

\A :只匹配string的開頭。

\b : 匹配空字符串,但僅僅在word的開頭或結尾。一個word被定義爲有字母,數字,或下劃線組成的序列,因此word的端(end)是空格或非字母,非數字,非下劃線。\b被定義爲\w \W字符之間的boundary(反之,也成立),或\wstring的開始端或結束端之間,好比,r'\bfoo\b'匹配'foo','foo.' '(foo)', 'bar foo baz'但不會匹配'foobar' 'foo3'.爲了兼容pythonstring,在字符範圍內\b表明backspace字符。

\B :  匹配空字符,但僅僅但它不在word的開頭或結尾時。這意味着r'py\B'將匹配'python','py3','py2',而不會匹配'py','py.','py!'. \B\b的反面,因此is also subject to the settings of LOCALE and UNICDOE.

\d :  當沒有明確UNICODE標誌位時,將匹配任意的decimal數字;這等同於[0-9].有了UNICODE時,將匹配whatever is classified as a decimal digit in the Unicode character properties database.

\D: 當沒有明確UNICODE標誌位時,將匹配任意的非decimal數字;這等同於[^0-9].有了UNICODE時,將匹配anything other than character marked as digits in the Unicode character properties database.

\s: 當沒有明確UNICODE標誌位時,將匹配任意的非空格字符;這等同於[^\t\n\r\f\v....

\S:

\w:這等同於[a-zA-Z0-9]

\W: 

\Z:

7.2.2. Module Contents

本模塊定義了一些函數,常量,和異常。一些函數是。。。的簡化版本。大部分應用都使用complied形式。

 

re.compile(pattern,flags=0)

    編譯一個正則表達式pattern爲正則表達式對象,可利用此對象的match()search()方法。

    RE的行爲可由flags改變。其值可爲下面變量的任何一個,或使用|OR操做混合起來。

prog = re.compile(pattern) result = prog.match(string)

等價於:

result = re.match(pattern, string)

但使用re.compile()爲了重用而保存最終的正則表達式對象是更有效的。

re.DEBUG:顯示有關compiled expression的調試信息。

re.I  re.IGNORECASE: 完成大小寫無關匹配;因此,像[A-Z]的表達式也將匹配小寫字母。這不受current locale影響。

re.L  re.LOCALE: 使得\w \W \b \B \s \S依賴與current locale

re.M re.MULTILINE: 明確此時,pattern字符'^'匹配string的開頭而且在每一行的開頭;'$'匹配string的結尾而且在每一行的結尾。默認狀況下,'^'只匹配string的開頭,'$'只匹配string的結尾。

re.S re.DOTALL: 使得'.'將匹配包含換行符在內的任意字符,沒有此flag時匹配除換行符外的任意字符。

re.U re.UNICODE:使得\w \W \b \B \s \S依賴與Unicode character properties database.

re.X re.VERBOSE: flag可以使你寫出好看的RE。除了字符類的空格和preceded by unescaped backslash的空格外其餘的在pattern中的空格會被忽略,

意味着下面等價:

a = re.compile(r"""\d +  # the integral part                    \.    # the decimal point                    \d *  # some fractional digits""", re.X) b = re.compile(r"\d+\.\d*")

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

    掃描string從中找到pattern匹配的位置並返回相應的MatchObject實例對象。若是沒有匹配返回None注意這不一樣於在string中找到0長度的匹配。

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

    若是在string的開始有0或多個字符匹配pattern並返回相應的MatchObject實例對象。若是沒有匹配返回None注意這不一樣於在string中找到0長度的匹配。

    注意甚至在multiline模式下re.match()將僅僅匹配string的開頭而不是每一行的開頭。

    若是你想要在string的任何地方locate a match,使用search()

re.split(pattern,string ,maxsplit=0,flags=0)

    split string by the occurrence of pattern。若是pattern加了圓括號,則全部pattern裏全部groups的內容做爲最終結果的list被返回。若是maxsplit0,則最多maxsplit個分片發生,而且string中剩下的內容做爲list中最後的元素。

>>> re.split('\W+', 'Words, words, words.') ['Words', 'words', 'words', ''] >>> re.split('(\W+)', 'Words, words, words.') ['Words', ', ', 'words', ', ', 'words', '.', ''] >>> re.split('\W+', 'Words, words, words.', 1) ['Words', 'words, words.'] >>> re.split('[a-f]+', '0a3B9', flags=re.IGNORECASE) ['0', '3', '9']

若是有捕獲groups(pattern或某個子pattern被圓括號括起來) in the seaparator而且它匹配字符串的開頭,結果將以空字符串開頭,空字符串結尾:

>>> re.split('(\W+)', '...words, words...') ['', '...', 'words', ', ', 'words', '...', '']

注意split毫不會在不匹配時split字符串:

>>> re.split('x*', 'foo') ['foo'] >>> re.split("(?m)^$", "foo\n\nbar\n") ['foo\n\nbar\n']

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

    list的形式返回string中全部的非重疊的匹配,每個匹配時list的一個元素。string被從左到右掃描,匹配。若是一個或多個groups被發現,則返回返回元素爲tuplelist

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

    對每個非重疊匹配返回MatchObject實例的inerator

re.sub(pattern,repl,string,count = 0,flags = 0)

    返回由repl替代string中每個非重疊匹配的字串後的string。若是沒有匹配被發現則原string被返回。repl能夠是string或函數,若是是string,則轉義字符被使用,好比\n是一個換行符,\rcarriage return,等等。不被識別的轉義字符\j are left alone.後向引用是\6表示group號爲6的被匹配的字串:

>>> re.sub(r'def\s+([a-zA-Z_][a-zA-Z_0-9]*)\s*\(\s*\):', ...        r'static PyObject*\npy_\1(void)\n{', ...        'def myfunc():') 'static PyObject*\npy_myfunc(void)\n{'

若是repl是函數,則對每個非重疊的引用此函數被調用一次。此函數把每一個MatchObject對象做爲函數參數,sub返回替換以後的字符串:

 

 >>> def dashrepl(matchobj):

 

...     if matchobj.group(0) == '-': return ' '

 

...     else: return '-' >>> re.sub('-{1,2}', dashrepl, 'pro----gram-files') 'pro--gram files'

>>> re.sub(r'\sAND\s', ' & ', 'Baked Beans And Spam', flags=re.IGNORECASE)

 

'Baked Beans & Spam'  

 

pattern能夠是stringRE對象

可選的參數count是被替換的最大數;是非負值。若是此參數別省略或爲0,則全部匹配被替換。僅當not adjacent to a previous match empty matchs被替換:sub('x*','-','abc')返回'-a-b-c-'.

除了字符轉義和後向引用外,\g<name>將使用被匹配的group名爲name的字串,此group定義爲(?P<name>...).\g<number>也使用了相應的group數;\g<2>等價於\2,但不與替換中的好比\g<2>0混淆。\20被解釋爲對group 20的引用,不是group 2的引用並後跟字面字符'0'。後向引用\g<0>替換了整個匹配的字串。

 

re.subn(pattern,repl,string ,count = 0,flags = 0)

    完成與sub一樣的操做,但返回一個tuple (new_string,number_of_subs_made).

re.escape(string)

    返回全部non-alphanumerics backslashed字串;

re.purge()

    清除RE緩存

exception re.error

    但一個無效的RE被傳遞給函數時Exceptionraised(好比,可能包含了unmatched parentheses)或在編譯或匹配時發生的錯誤。但若是string不匹配RE是不會發生error

7.2.3. Regular Expression Objects

class re.RegexObject

    RegexObject類支持下面的方法和屬性:

search(string[, pos[, endpos]])

    掃描此string並找RE匹配此string的位置,並返回相應的MatchObject對象。若是不匹配返回None;注意這不一樣於找到0長度的match

    第二個可選的參數pos給在出string中匹配開始的索引位置;默認是0即從頭開始匹配。這不徹底同於對string的分片操做;'^'匹配string的開頭或newline的後面位置,但...

       可選的參數endpos限制了string被搜索多遠;就好像string只有endpos長,因此對匹配來說僅僅有pos endpos-1的字符被搜索。若是endpos小於pos,不會有匹配,不然,若是rx被編譯成了RE對象,re.search(string,0,50)等價於rx.search(string[:50],0)

>>> pattern = re.compile("d") >>> pattern.search("dog")     # Match at index 0 <_sre.SRE_Match object at ...> >>> pattern.search("dog", 1# No match; search doesn't include the "d"

match(string[,pos[,endpos]])

    若是在string的開頭有0個或多個字符匹配此RE,則返回相應的MatchObject實例對象。若是沒有匹配則返回None;注意,這不一樣於0長度匹配。

可選的posendpossearch()

>>> pattern = re.compile("o") >>> pattern.match("dog")      # No match as "o" is not at the start of "dog". >>> pattern.match("dog", 1)   # Match as "o" is the 2nd character of "dog". <_sre.SRE_Match object at ...>

    若是你想要在string中定位一個match,使用search()而不是match()

split(string,maxsplit = 0)

    等同於split()函數,使用compiled pattern

findall(string[, pos[, endpos]])

    類似與findall()函數,使用compiled pattern,但也接受可選的參數,此些參數同match()中。

finditer(string[, pos[, endpos]])

    類似與finditer()函數,使用compiled pattern,但也接受可選的參數,此些參數同match()中。

sub(repl,string,count = 0)

    等價於sub()函數,使用compiled pattern

subn(repl,string,count = 0)

    等價於subn()函數,使用compiled pattern

flags

    regex匹配flags 

groups

    patten中被捕獲的groups

groupindex

    一個字典,此字典將由(?P<id>)定義的group名與group數一一對應。若是在patter中沒有使用

    groups(pattern或某個    pattern沒有被圓括號括起來)則此字典爲empty

pattern

    the pattern string from which the RE object was compiled

7.2.4. Match Objects

class re.MatchObject

    MatchObject老是有值爲True的布爾值,因此你能夠測試好比matct()

    expand(template)

        返回對template字符串進行backlash替換以後而得到的字符串,正如sub()方法那樣。轉義好比\n被轉換爲恰當的字符,數字後引用(\1 ,\2)和有名後引用(\g<1>,\g<name>)被相應group的內容所替換。

    group([group1, ...])

         返回匹配的一個或多個的子group。若是有一個參數,則結果是一個單string,若是有多個參數,結果是每一個參數爲一個itemtuple。沒有參數時,group1默認爲0(整個匹配被返回)。若是groupN0,相應的返回值是整個匹配的string;若是參數在[1..99]範圍內,結果是匹配相應的groupstring。若是group number爲負或大於patter中定義的group number,則raise一個IndexError異常。若是一個group包含在pattern中且沒有匹配,則相應的結果爲None。若是一個group包含在pattern中且屢次被匹配,則最後那次匹配被返回。

>>> m = re.match(r"(\w+) (\w+)", "Isaac Newton, physicist") >>> m.group(0)       # The entire match 'Isaac Newton' >>> m.group(1)       # The first parenthesized subgroup. 'Isaac' >>> m.group(2)       # The second parenthesized subgroup. 'Newton' >>> m.group(1, 2)    # Multiple arguments give us a tuple. ('Isaac', 'Newton')

若是RE使用了(?P<name>...)語法,則groupN參數也能夠是個string,此stringgroup name給出。若是string參數不被用做pattern中的group名,raise一個IndexError

一個適度複雜的例子:

>>> m = re.match(r"(?P<first_name>\w+) (?P<last_name>\w+)", "Malcolm Reynolds") >>> m.group('first_name') 'Malcolm' >>> m.group('last_name') 'Reynolds'

有名的groups也可由index來引用:

>>> m.group(1) 'Malcolm' >>> m.group(2) 'Reynolds'

若是一個group匹配了屢次,只是最後那次匹配 is accessible

>>> m = re.match(r"(..)+", "a1b2c3"# Matches 3 times. >>> m.group(1)                        # Returns only the last match. 'c3'

    groups([default])

        返回全部由subgroup匹配造成的tuple,從1到開始。default參數不會參與匹配;默認爲None

        好比:

>>> m = re.match(r"(\d+)\.(\d+)", "24.1632") >>> m.groups() ('24', '1632')

不是全部的group會參與到匹配中。若是默認值未給出則groups將默認爲None,不然值爲默認值:

>>> m = re.match(r"(\d+)\.?(\d+)?", "24") >>> m.groups()      # Second group defaults to None. ('24', None) >>> m.groups('0')   # Now, the second group defaults to '0'. ('24', '0')

    groupdict([default])

        返回一個字典,此字典包含了keysubgroup value爲相應的匹配字串。若是默認值未給出則groups將默認爲None,不然值爲默認值:

>>> m = re.match(r"(?P<first_name>\w+) (?P<last_name>\w+)", "Malcolm Reynolds") >>> m.groupdict(){'first_name': 'Malcolm', 'last_name': 'Reynolds'}

    start([group])

    end([group])

           返回每一個匹配的group的開始和結束位置;group默認爲0(即整個匹配的字串)。若是group存在但沒有匹配時返回-1.對一個match對象m,一個group g知足一個匹配,則g匹配的字串(m.group(g)):

m.string[m.start(g):m.end(g)]

 注意m.start(group)group匹配一個null字符串時將等同於m.end(group)。好比m = re.search('b(c?)','cba')執行後m.start(0)1m.end(0)2m.start(1)m.end(1)都是2m.start(2)raise一個IndexError異常。

一個將從email地址中刪除remove_this的例子

>>> email = "tony@tiremove_thisger.net" >>> m = re.search("remove_this", email) >>> email[:m.start()] + email[m.end():] 'tony@tiger.net'

    span([group])

        MatchObject m來講返回一個(m.start(group), m,end(group))tuple。注意若是group不匹配結果是(-1, -1)

group默認爲0,整個匹配。

    pos

        此值傳給RegexObject對象的search()match()方法。這是RE引擎開始匹配的index的開始位置

    endpos

        此值傳給RegexObject對象的search()match()方法。這是RE引擎開始匹配的index的結束位置

    lastindex   

    lastgroup

    re

    string

7.2.5. Examples

7.2.5.1. Checking For a Pair

在整個例子中,咱們將使用下面的helpler函數顯示math objects,使之結果更美觀:

def displaymatch(match):     if match is None:         return None     return '<Match: %r, groups=%r>' % (match.group(), match.groups())

假設你正在寫一個撲克程序,此程序中每一個玩家的手由5個字符的字符串表明,其中每個字符表明一個卡片,'a'表明ace'k'表明king 'q'表明queen 'j'表明jack 't'表明10以及29表明了卡的值。

爲了查看一個給出的string是不是個有效地hand,能夠以下怎麼作:

>>> valid = re.compile(r"^[a2-9tjqk]{5}$") >>> displaymatch(valid.match("akt5q"))  # Valid. "<Match: 'akt5q', groups=()>" >>> displaymatch(valid.match("akt5e"))  # Invalid. >>> displaymatch(valid.match("akt"))    # Invalid. >>> displaymatch(valid.match("727ak"))  # Valid. "<Match: '727ak', groups=()>"

最後一個hand "727ak",包含了一對或2個相同值的卡。可以使用後向引用:

>>> pair = re.compile(r".*(.).*\1") >>> displaymatch(pair.match("717ak"))     # Pair of 7s. "<Match: '717', groups=('7',)>" >>> displaymatch(pair.match("718ak"))     # No pairs. >>> displaymatch(pair.match("354aa"))     # Pair of aces. "<Match: '354aa', groups=('a',)>"

7.2.5.2. Simulating scanf()

Python中當前沒有相等價的scanf()函數,RE通常比scanf()格式更強大,也更囉嗦,下表或多或少提供了一些等價於scanf()函數的RE格式

scanf() Token

Regular Expression

%c

.

%5c

.{5}

%d

[-+]?\d+

%e%E%f%g

[-+]?(\d+(\.\d*)?|\.\d+)([eE][-+]?\d+)?

%i

[-+]?(0[xX][\dA-Fa-f]+|0[0-7]*|\d+)

%o

0[0-7]*

%s

\S+

%u

\d+

%x%X

0[xX][\dA-Fa-f]+

爲了從像下面的string中提取文件名和數字:

usr/sbin/sendmail - 0 errors, 4 warnings

你會像下面這樣使用scanf()格式:

%s - %d errors, %d warnings

而等價的RE會是:

(\S+) - (\d+) errors, (\d+) warnings

7.2.5.3. search() vs. match()

Python提供了2個不一樣的基於RE的基本操做:re.match()用來僅僅檢查string的開頭,而re.search()檢查string中任何一個位置開始的匹配(perl默認就是這樣)好比:

>>> re.match("c", "abcdef"# No match >>> re.search("c", "abcdef") # Match <_sre.SRE_Match object at ...>

'^'開始的RE可被用在search()中以便來約束在string開頭處的匹配:

>>> re.match("c", "abcdef"# No match >>> re.search("^c", "abcdef") # No match >>> re.search("^a", "abcdef"# Match <_sre.SRE_Match object at ...>

但,在MULTILINE模式下,match()函數僅僅匹配string的開頭,但以'^'開頭的REsearch()函數可匹配每行的開頭。

>>> re.match('X', 'A\nB\nX', re.MULTILINE)  # No match >>> re.search('^X', 'A\nB\nX', re.MULTILINE)  # Match <_sre.SRE_Match object at ...>

7.2.5.4. Making a Phonebook

split()函數以patternstring分隔造成一個list。此方法在將文本數據轉化爲易讀易修改的數據結構時顯得很與價值。

首先,輸入正常意義下來自於文件,這裏咱們使用triple-quoted字符串語法:

>>> text = """Ross McFluff: 834.345.1254 155 Elm Street ... ... Ronald Heathmore: 892.345.3428 436 Finley Avenue ... Frank Burger: 925.541.7625 662 South Dogwood Way ... ... ... Heather Albrecht: 548.326.4584 919 Park Place"""

字符串給一個或多個空行分隔開。如今咱們將string轉化爲每個非空行是list中一個元素而造成的list

>>> entries = re.split("\n+", text) >>> entries ['Ross McFluff: 834.345.1254 155 Elm Street', 'Ronald Heathmore: 892.345.3428 436 Finley Avenue', 'Frank Burger: 925.541.7625 662 South Dogwood Way', 'Heather Albrecht: 548.326.4584 919 Park Place']

最後,將每一行在split成一個first-name last-name telephone-number address構成的list。使用maxsplit參數,由於address佔有空間:

>>> [re.split(":? ", entry, 3) for entry in entries] [['Ross', 'McFluff', '834.345.1254', '155 Elm Street'], ['Ronald', 'Heathmore', '892.345.3428', '436 Finley Avenue'], ['Frank', 'Burger', '925.541.7625', '662 South Dogwood Way'], ['Heather', 'Albrecht', '548.326.4584', '919 Park Place']]

':?'匹配last-name的冒號。若是maxsplit4咱們能夠從street-name中分隔出housr-number

>>> [re.split(":? ", entry, 4) for entry in entries]

[['Ross', 'McFluff', '834.345.1254', '155', 'Elm Street'],

['Ronald', 'Heathmore', '892.345.3428', '436', 'Finley Avenue'],

['Frank', 'Burger', '925.541.7625', '662', 'South Dogwood Way'],

['Heather', 'Albrecht', '548.326.4584', '919', 'Park Place']]

7.2.5.5. Text Munging

sub()string或函數的結果替換每一次pattern的匹配。這個例子顯示了使用sub()函數repl爲一個函數,在此函數中"munge" text,或者隨機化除了第一個和最後一個字符外的字符:

>>> def repl(m):

...   inner_word = list(m.group(2))

...   random.shuffle(inner_word)

...   return m.group(1) + "".join(inner_word) + m.group(3)

>>> text = "Professor Abdolmalek, please report your absences promptly."

>>> re.sub(r"(\w)(\w+)(\w)", repl, text)

'Poefsrosr Aealmlobdk, pslaee reorpt your abnseces plmrptoy.'

>>> re.sub(r"(\w)(\w+)(\w)", repl, text)

'Pofsroser Aodlambelk, plasee reoprt yuor asnebces potlmrpy.'

7.2.5.6. Finding all Adverbs

findall()匹配全部的pattern,不只僅是search()那樣子匹配第一個。好比,若是某個做家想要在文本中找到全部的動詞,他或她可像以下這樣使用:

>>> text = "He was carefully disguised but captured quickly by police."

>>> re.findall(r"\w+ly", text)

['carefully', 'quickly']

7.2.5.7. Finding all Adverbs and their Positions

若是某人想要獲得有關匹配更多的信息,finditer()是頗有用的,由於它提供了MathcObject實例對象。接着前面的例子,若是某個做家想要在某個文本中找到動詞以及出現的位置,可以使用finditer():

>>> text = "He was carefully disguised but captured quickly by police."

>>> for m in re.finditer(r"\w+ly", text):

...     print '%02d-%02d: %s' % (m.start(), m.end(), m.group(0))

07-16: carefully

40-47: quickly

7.2.5.8. Raw String Notation

raw stirng概念(r"text")使得RE健全。沒有此,每一個在RE中的反斜線'\'可能必需要前綴另外一個反斜線來轉義它,下面代碼功能上等價:

>>> re.match(r"\W(.)\1\W", " ff ")

<_sre.SRE_Match object at ...>

>>> re.match("\\W(.)\\1\\W", " ff ")

<_sre.SRE_Match object at ...>

當某人想要匹配一個字面上的反斜線是,必須在RE中轉義。有了raw string後即r"\\"。沒有raw string時必須使用"\\\\",下面代碼等價:

>>> re.match(r"\\", r"\\")

<_sre.SRE_Match object at ...>

>>> re.match("\\\\", r"\\")

<_sre.SRE_Match object at ...>

相關文章
相關標籤/搜索