python標准庫介紹——5 re模塊詳解


== re 模塊==


        "Some people, when confronted with a problem, think 'I know, I'll use regular expressions.' Now they have two problems."

        - Jamie Zawinski, on comp.lang.emacs

``re`` 模塊提供了一系列功能強大的正則表達式 (regular expression) 工具, 
它們允許你快速檢查給定字符串是否與給定的模式匹配 (使用 ``match`` 函數), 
或者包含這個模式 (使用 ``search`` 函數). 正則表達式是以緊湊(也很神秘)的語法寫出的字符串模式. 

``match`` 嘗試從字符串的起始匹配一個模式, 如 [Example 1-54 #eg-1-54] 所示. 
如果模式匹配了某些內容 (包括空字符串, 如果模式允許的話) , 
它將返回一個匹配對象. 使用它的 ``group`` 方法可以找出匹配的內容. 

====Example 1-54. 使用 re 模塊來匹配字符串====[eg-1-54]

```
File: re-example-1.py

import re

text = "The Attila the Hun Show"

# a single character 單個字符
m = re.match(".", text)
if m: print repr("."), "=>", repr(m.group(0))

# any string of characters 任何字符串
m = re.match(".*", text)
if m: print repr(".*"), "=>", repr(m.group(0))

# a string of letters (at least one) 只包含字母的字符串(至少一個)
m = re.match("\w+", text)
if m: print repr("\w+"), "=>", repr(m.group(0))

# a string of digits 只包含數字的字符串
m = re.match("\d+", text)
if m: print repr("\d+"), "=>", repr(m.group(0))

*B* '.' => 'T'
'.*' => 'The Attila the Hun Show'
'\\w+' => 'The'*b*
```

可以使用圓括號在模式中標記區域. 找到匹配后, ``group`` 方法可以抽取這些區域的內容,
如 [Example 1-55 #eg-1-55] 所示. ``group(1)`` 會返回第一組的內容, ``group(2)`` 
返回第二組的內容, 這樣... 如果你傳遞多個組數給 ``group`` 函數, 它會返回一個元組. 

====Example 1-55. 使用 re 模塊抽出匹配的子字符串====[eg-1-55]

```
File: re-example-2.py

import re

text ="10/15/99"

m = re.match("(\d{2})/(\d{2})/(\d{2,4})", text)
if m:
    print m.group(1, 2, 3)

*B*('10', '15', '99')*b*
```

``search`` 函數會在字符串內查找模式匹配, 如 [Example 1-56 #eg-1-56] 所示. 
它在所有可能的字符位置嘗試匹配模式, 從最左邊開始, 一旦找到匹配就返回一個匹配對象. 
如果沒有找到相應的匹配, 就返回 //None// . 

====Example 1-56. 使用 re 模塊搜索子字符串====[eg-1-56]

```
File: re-example-3.py

import re

text = "Example 3: There is 1 date 10/25/95 in here!"

m = re.search("(\d{1,2})/(\d{1,2})/(\d{2,4})", text)

print m.group(1), m.group(2), m.group(3)

month, day, year = m.group(1, 2, 3)
print month, day, year

date = m.group(0)
print date

*B*10 25 95
10 25 95
10/25/95*b*
```

[Example 1-57 #eg-1-57] 中展示了 ``sub`` 函數, 它可以使用另個字符串替代匹配模式.

====Example 1-57. 使用 re 模塊替換子字符串====[eg-1-57]

```
File: re-example-4.py

import re

text = "you're no fun anymore..."

# literal replace (string.replace is faster)
# 文字替換 (string.replace 速度更快)
print re.sub("fun", "entertaining", text)

# collapse all non-letter sequences to a single dash 
# 將所有非字母序列轉換為一個"-"(dansh,破折號)
print re.sub("[^\w]+", "-", text)

# convert all words to beeps 
# 將所有單詞替換為 BEEP
print re.sub("\S+", "-BEEP-", text)

*B*you're no entertaining anymore...
you-re-no-fun-anymore-
-BEEP- -BEEP- -BEEP- -BEEP-*b*
```

你也可以通過回調 (callback) 函數使用 ``sub`` 來替換指定模式. 
[Example 1-58 #eg-1-58] 展示了如何預編譯模式. 

====Example 1-58. 使用 re 模塊替換字符串(通過回調函數)====[eg-1-58]

```
File: re-example-5.py

import re
import string

text = "a line of text\\012another line of text\\012etc..."

def octal(match):
    # replace octal code with corresponding ASCII character
    # 使用對應 ASCII 字符替換八進制代碼
    return chr(string.atoi(match.group(1), 8))

octal_pattern = re.compile(r"\\(\d\d\d)")

print text
print octal_pattern.sub(octal, text)

*B*a line of text\012another line of text\012etc...
a line of text
another line of text
etc...*b*
```

如果你不編譯, ``re`` 模塊會為你緩存一個編譯后版本, 所有的小腳本中, 
通常不需要編譯正則表達式. Python1.5.2 中, 緩存中可以容納 20 個匹配模式, 而在 2.0 中, 
緩存則可以容納 100 個匹配模式. 

最后, [Example 1-59 #eg-1-59] 用一個模式列表匹配一個字符串. 這些模式將會組合為一個模式, 並預編譯以節省時間. 

====Example 1-59. 使用 re 模塊匹配多個模式中的一個====[eg-1-59]

```
File: re-example-6.py

import re, string

def combined_pattern(patterns):
    p = re.compile(
        string.join(map(lambda x: "("+x+")", patterns), "|")
        )
    def fixup(v, m=p.match, r=range(0,len(patterns))):
        try:
            regs = m(v).regs
        except AttributeError:
            return None # no match, so m.regs will fail
        else:
            for i in r:
                if regs[i+1] != (-1, -1):
                    return i
    return fixup

#
# try it out!

patterns = [
    r"\d+",
    r"abc\d{2,4}",
    r"p\w+"
]

p = combined_pattern(patterns)

print p("129391")
print p("abc800")
print p("abc1600")
print p("python")
print p("perl")
print p("tcl")

*B*0
1
1
2
2
None*b*
```

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM