re 正則表達式操作
本模塊提供了類似於Perl的正則表達式匹配操作。要匹配的模式和字符串可以是Unicode字符串以及8位字符串。
正則表達式使用反斜杠字符('\')來表示特殊的形式或者來允許使用特殊的字符而不要啟用它們特殊的含義。這與字符串字面值中相同目的的相同字符的用法沖突;例如,要匹配一個反斜線字面值,你必須寫成'\\\\'作為模式字符串,因為正則表達式必須是\\,每個反斜線在Python字符串字面值內部必須表達成\\。
解決的辦法是使用Python的原始字符串符號表示正則表達式的模式;在以'r'為前綴的字符串字面值中,反斜杠不會以任何特殊的方式處理。所以r"\n"是一個包含'\'和'n'兩個字符的字符串,而"\n"是包含一個換行符的單字符字符串。通常在Python代碼中,模式的表示使用這種原始字符串符號。
重要的注意事項是大部分正則表達式操作可以利用模塊級別的函數和RegexObject的方法。這些函數是快捷的方式,它們不要求你首先編譯一個正則表達式對象,但會遺漏一些調優的參數。
請參見
- Mastering Regular Expressions 《精通正則表達式》
- O’Reilly 該書第 2 版不再涵蓋Python內容,但其第 1 版中涵蓋了很多寫得不錯、非常詳細的正則表達式模式。
7.2.1. 正則表達式語法
正則表達式(或RE)指定一組匹配它字符串;此模塊中的函數讓你檢查一個特定的字符串是否匹配給定的正則表達式(或給定的正則表達式是否匹配特定的字符串,這可歸結為同一件事)。
正則表達式可以連接以形成新的正則表達式;如果A和B兩個都是正則表達式,那么AB也是正則表達式。一般來說,如果字符串p匹配A且另一個字符串q匹配B,那么字符串pq將匹配AB。除非A或B包含低優先級的操作;A和B之間存在邊界條件;或有編號的組的引用。因此,復雜的表達式可以輕松地從這里所描述的更簡單的原始表達式構建。關於理論的細節及正則表達式的實現,請參閱上文引用的Friedl的書或任何一本有關編譯器構造的教科書。
下面簡要說明了正則表達式的格式。進一步的信息和更友好的演示,請參閱正則表達式HOWTO。
正則表達式可以包含特殊和普通字符。最普通的字符,如'A'、'a'、或'0'是最簡單的正則表達式;它們簡單地匹配它們自己。你可以連接普通字符,所以last匹配字符串'last'。(在本節剩下的部分,我們將把正則表達式寫成不帶引號的形式這種獨特風格,要匹配的字符串寫成帶引號的形式'用單引號'。)
某些字符,比如'|'或'(',比較特殊。特殊字符要么表示某個類別的普通字符,要么影響它們周圍的正則表達式如何解釋。正則表達式的模式字符串不可以包含空字節,但可以使用\number符號指定空字節,例如'\x00'。
特殊字符有:
- '.'
- (點號。)在默認模式下,匹配除換行以外的任意字符.如果 DOTALL 標志被指定, 則匹配包括換行符在內的所有字符.
- '^'
- (脫字符號。)在默認模式下匹配字符串的起始位置, 在MULTILINE模式下也匹配換行符之后的位置.
- '$'
- 匹配字符串的末尾或者字符串末尾換行符之前的位置,在MULTILINE模式下還匹配換行符之前的位置。foo既匹配‘foo’也匹配‘foobar’,但是foo$只匹配‘foo’。更有趣的是,正常情況下foo.$只匹配'foo1\nfoo2\n' ‘foo2’,但是在MULTILINE模式下還能匹配‘foo1’;在'foo\n'中搜索單個$將找到兩個(空的)匹配:一個是換行符之前,一個是字符串的末尾。
- '*'
- 匹配前面重復出現的正則表達式零次或多次,盡可能多的匹配。ab*將匹配‘a’、‘ab’或‘a’ 后面跟隨任意數目的‘b’。
- '+'
- 引起生成的RE匹配1個或多個前導的RE,盡可能多的匹配。ab+將匹配‘a’之后跟隨任意多個數目不為零的‘b’,它將不能匹配單純的一個‘a’。
- '?'
- 引起生成的RE匹配0個或1個前導的RE。ab?將匹配‘a’或者‘ab’。
- *?, +?, ??
- '*'、'+'和'?'限定符是貪婪的; 它們匹配盡可能多的文本。有時這個行為不是想要的;如果用正則表達式<.*>來匹配'<H1>title</H1>',它將匹配完整的字符串,而不會只是'<H1>'。在限定符之后加上'?'將使得匹配以非貪婪的或最小的方式進行;因為它將匹配盡可能少的字符。在剛才的表達式中使用.*?將只匹配'<H1>'。
- {m}
- 表示精確匹配前面的正則表達式的m個拷貝;較少的匹配將導致整個表達式不能匹配。例如,a{6}將精確匹配6個'a'字符,5個將不能匹配。
- {m,n}
- 引起生成的正則表達式匹配前導正則表達式的m到n個重復,嘗試匹配盡可能多的重復。例如,a{3,5}將匹配3到5個'a'字符。省略m表示下界為0,省略n表示上界無限大。舉個例子,a{4,}b將匹配aaaab或一千個'a'字符后跟隨一個b,但不能匹配aaab。逗號不可以省略,否則該修改符將與前面的形式混淆。
- {m,n}?
- 例如,對於6個字符的字符串'aaaaaa',a{3,5}將匹配5個'a'字符,而a{3,5}?將只匹配3個字符。
- '\'
-
對任一特殊字符進行轉義(允許您匹配字符(如'*',' ? ',等等),或只是一個特殊的序列;特殊序列在下面討論。
如果你不使用原始字符串來表達模式,記住在字符串字面值中Python也使用反斜杠作為轉義序列;如果轉義序列不能被Python解析器識別,那么結果字符串中包含反斜杠和后面的字符。但是,如果Python會識別所產生的序列,反斜杠應該重復兩次。這比較復雜和難以理解,因此強烈建議你為所有即使是最簡單的表達式使用原始字符串。
- []
-
用來表示一個字符集合。在一個集合中:
- 字符可以一個一個列出來,例如[amk]將匹配'a'、'm'或'k'。
- 通過給出兩個字符並用'-'分隔,可以給出一段范圍的字符,例如[a-z]將匹配任意一個小寫的ASCII字符,[0-5][0-9]將匹配00到59之間所有的兩位數字,[0-9A-Fa-f]將匹配任意一個十六進制數字。如果-被轉義(例如[a\-z])或者如果它位於第一個或最后一個字符(例如[a-]),它將只匹配一個字面值'-'。
- 在集合內部,特殊字數將失去它們特殊的含義。例如,[(+*)]將匹配字符字面值'('、'+'、'*'或')'。
- 在集合中還接受字符類別,例如\w或\S(在下文定義),盡管它們匹配的字符取決於LOCALE或UNICODE模式是否是強制的。
- 不在一段范圍之內的字符可以通過補集匹配。如果集合的第一個字符是'^',那么所有不在集合中的字符都將被匹配。例如,[^5]將匹配除'5'之外的所有字符,[^^]將匹配除'^'之外的所有字符。^如果不是集合中的第一個字符則沒有特殊的含義。
- 若要匹配集合中的一個字符字面值']',可以在它前面放一個反斜線或者將它放在集合的開始。例如,[()[\]{}]和[]()[{}]都將匹配一個圓括號。
- '|'
- A|B, 此處的 A 和 B 可以是任意的正則表達式, 創建的這個正則表達式要么匹配 A 要么匹配 B. '|'可以用來隔開任意個數的正則表達式,着同樣可以用在組里面。 當掃描字符串時,REs 被用'|'從左到右分隔。當一個模式被完全匹配時,這個被匹配的模式就被接受。這意味着一旦 匹配A , B 就不在被嘗試, 即使他會產生更長的整體匹配. 換句話說, '|' 不是貪婪操作符. 匹配符號 '|',用 |, 或者把它包含在組內, 就像是 [|].
- (...)
- 匹配任何在圓括號內的正則表達式, 並表明分組的開始和結束; 分組的內容在完成匹配后可以提取出來,而且可以在后面的字符串中用特殊的number序列匹配,下面有描述。若要匹配字面值'('或')',請使用( or ),或它們放入字符類的括號中:[(] [)]。
- (?...)
- This is an extension notation (a '?' following a '(' is not meaningful otherwise). The first character after the '?' determines what the meaning and further syntax of the construct is. Extensions usually do not create a new group; (?P<name>...) is the only exception to this rule.Following are the currently supported extensions.
- (?iLmsux)
-
(集合'i', 'L', 'm', 's', 'u', 'x'中的一個或多個字母。)這個分組空字符串;這些字母給真個正則表達式設置相應的標記:
re.I
(忽略大小寫),re.L
(依賴區域設置),re.M
(多行),re.S
(點號匹配所有字符),re.U
(依賴Unicode),re.X
(詳細模式)。(這些標志在模塊的內容中講述)。它用於如果你想要包含這些標志作為正則表達式的一部分,而不是將flag參數傳遞給re.compile()函數。請注意,(?x)標志更改解析表達的方式。它應使用在表達式字符串的開始,或一個或多個空白字符之后。如果在這個標志之前有非空白字符,結果是未定義的。
- (?:...)
- 括號形式的正則表達式的非匹配版本。匹配括號中的任何正則表達式,但是匹配的子字符串不能在匹配后提取或在模式中引用。
- (?P<name>...)
-
通過符號組名稱name可以訪問類似於常規的括號,但由組匹配的子字符串。組名必須是有效的 Python 標識符,並且每個組名必須在正則表達式內只有一次定義。海員象征性的組織也是帶編號的組,就好像組未被命名。
Named groups can be referenced in three contexts. If the pattern is (?P<quote>['"]).*?(?P=quote) (i.e. matching a string quoted with either single or double quotes):
Context of reference to group “quote” Ways to reference it in the same pattern itself - (?P=quote) (as shown)
- \1
when processing match object m - m.group('quote')
- m.end('quote') (etc.)
in a string passed to the repl argument of re.sub() - \g<quote>
- \g<1>
- \1
- (?P=name)
- A backreference to a named group; 反向關聯一個已被命名的字符串組。 它將匹配之前被關聯到name中的所有內容。
- (?#...)
- 一條注釋;圓括號內容可簡單忽略。
- (?=...)
- Matches if ... matches next, but doesn’t consume any of the string. This is called a lookahead assertion. For example, Isaac (?=Asimov) will match 'Isaac ' only if it’s followed by 'Asimov'.
- (?!...)
- Matches if ... doesn’t match next. This is a negative lookahead assertion. For example, Isaac (?!Asimov) will match 'Isaac ' only if it’s notfollowed by 'Asimov'.
- (?<=...)
-
如果在字符串中的當前位置之前由...匹配項的比賽,在當前的位置結束。這就被所謂的積極回顧后發斷言。 (? < = abc) def將發現一個匹配abcdef,因為預測先行將備份 3 個字符,並檢查是否包含的模式匹配。包含的模式必須只匹配固定長度的字符串,這意味着允許abc 或a|b 的,但a* 和a{3,4} 不允許。請注意,開始與正預測先行斷言的模式將不匹配開頭的字符串被搜查 ;您將最有可能想要使用search ()函數,而不是match ()函數:
>>> import re >>> m = re.search('(?<=abc)def', 'abcdef') >>> m.group(0) 'def'
本示例查看后面一個連字符的詞:
>>> m = re.search('(?<=-)\w+', 'spam-egg') >>> m.group(0) 'egg'
- (?<!...)
- 如果字符串的當前位置不匹配之前的 .... 這叫做 否定性回顧斷言. Similar to positive lookbehind assertions, the contained pattern must only match strings of some fixed length. Patterns which start with negative lookbehind assertions may match at the beginning of the string being searched.
- (?(id/name)yes-pattern|no-pattern)
-
Will try to match with yes-pattern if the group with given id or name exists, and with no-pattern if it doesn’t. no-pattern is optional and can be omitted. For example, (<)?(w+@w+(?:.w+)+)(?(1)>) is a poor email matching pattern, which will match with '<user@host.com>' as well as 'user@host.com', but not with '<user@host.com'.
在 2.4 版本新。
- \number
- Matches the contents of the group of the same number. Groups are numbered starting from 1. For example, (.+) 1 matches 'the the' or '55 55', but not 'thethe' (note the space after the group). This special sequence can only be used to match one of the first 99 groups. If the first digit of number is 0, or number is 3 octal digits long, it will not be interpreted as a group match, but as the character with octal value number.Inside the '[' and ']' of a character class, all numeric escapes are treated as characters.
- \A
- Matches only at the start of the string.
- \b
- Matches the empty string, but only at the beginning or end of a word. A word is defined as a sequence of alphanumeric or underscore characters, so the end of a word is indicated by whitespace or a non-alphanumeric, non-underscore character.Note that formally, is defined as the boundary between a w and a W character (or vice versa), or between w and the beginning/end of the string, so the precise set of characters deemed to be alphanumeric depends on the values of the UNICODE and LOCALE flags. For example, r'\bfoo\b' matches 'foo', 'foo.', '(foo)','bar foo baz' but not 'foobar' or 'foo3'. Inside a character range, represents the backspace character, for compatibility with Python’s string literals.
- \B
- Matches the empty string, but only when it is not at the beginning or end of a word. This means that r'py\B' matches 'python', 'py3', 'py2', but not 'py', 'py.', or 'py!'.\B is just the opposite of \b, so is also subject to the settings of LOCALE and UNICODE.
- \d
- When the UNICODE flag is not specified, matches any decimal digit; this is equivalent to the set [0-9].With UNICODE, it will match whatever is classified as a decimal digit in the Unicode character properties database.
- \D
- When the UNICODE flag is not specified, matches any non-digit character; this is equivalent to the set [^0-9]. With UNICODE, it will match anything other than character marked as digits in the Unicode character properties database.
- \s
- When the UNICODE flag is not specified, it matches any whitespace character, this is equivalent to the set [ \t\n\r\f\v]. The LOCALE flag has no extra effect on matching of the space. If UNICODE is set, this will match the characters [ \t\n\r\f\v] plus whatever is classified as space in the Unicode character properties database.
- \S
- When the UNICODE flags is not specified, matches any non-whitespace character; this is equivalent to the set [^ \t\n\r\f\v]. The LOCALE flag has no extra effect on non-whitespace match. If UNICODE is set, then any character not marked as space in the Unicode character properties database is matched.
- \w
- When the LOCALE and UNICODE flags are not specified, matches any alphanumeric character and the underscore; this is equivalent to the set [a-zA-Z0-9_]. With LOCALE, it will match the set [0-9_] plus whatever characters are defined as alphanumeric for the current locale. If UNICODE is set, this will match the characters [0-9_] plus whatever is classified as alphanumeric in the Unicode character properties database.
- \W
- When the LOCALE and UNICODE flags are not specified, matches any non-alphanumeric character; this is equivalent to the set [^a-zA-Z0-9_]. WithLOCALE, it will match any character not in the set [0-9_], and not defined as alphanumeric for the current locale. If UNICODE is set, this will match anything other than [0-9_] plus characters classied as not alphanumeric in the Unicode character properties database.
- \Z
- 只在字符串的結尾處進行匹配
如果區域設置和UNICODE標志包括為一個特定的序列,區域設置標志可將第一次跟着UNICODE的生效。
由正則表達式分析器也接受大多數支持通過 Python 字符串的標准轉義:
\a \b \f \n
\r \t \v \x
\\
(請注意,用來表示單詞邊界,並意味着"退格鍵"只能在字符類的內部。)
八進制轉義中有限的形式包括: 如果第一個數字為 0,或者如果有三個八進制數字,它被認為是八進制轉義符。否則,它是組引用。字符串文本總是八進制轉義頂多是三個數字的長度。
1.2. Module Contents
模塊定義了幾個函數、 常量和異常。某些功能是充分的特色方法的已編譯的正則表達式的簡化的版本。大多數非平凡應用程序總是使用的已編譯的形式。
- re.compile(pattern, flags=0)
-
將正則表達式模式編譯成一個正則表達式對象,它可以用於匹配使用它的match ()和search ()方法,如下所述。
可以通過指定flags值修改表達式的行為。值可以是任何以下變量,使用組合 OR ( |運算符)。
序列
prog = re.compile(pattern) result = prog.match(string)
等效於
result = re.match(pattern, string)
但使用re.compile()和保存所產生的正則表達式對象重用效率更高時該表達式會在單個程序中多次使用。
- re.DEBUG
-
顯示調試信息編譯的表達式。
- re.I
- re.IGNORECASE
-
執行不區分大小寫的匹配 ;如[A-Z]表達式將太匹配小寫字母。這不被受當前的區域設置。
- re.L
- re.LOCALE
-
Make \w, \W, \b, \B, \s and \S dependent on the current locale.
- re.M
- re.MULTILINE
-
當指定時,模式字符' ^'匹配字符串的開頭以及每個行的開頭(緊接每個換行符); 模式字符'$'匹配字符串的末尾以及每一行的結尾(緊靠每個換行符之前)。默認情況下, '^'只匹配字符串的開始,'$'只匹配字符串的末尾和字符串末尾換行符(如果有的話)之前的位置。
- re.S
- re.DOTALL
-
使'.'特殊字符匹配任何字符,包括換行 ;如果沒有此標志, '.'將匹配任何內容除換行符。
- re.U
- re.UNICODE
-
使得\w, \W, \b, \B, \d, \D, \s和 \S 取決於UNICODE定義的字符屬性.
在 2.0 版中的新。
- re.X
- re.VERBOSE
-
此標志允許您編寫正則表達式,看起來更好。在模式中的空白將被忽略,除非當在字符類或者前面非轉義反斜杠,和,當一條線包含一個'#'既不在字符類中或由非轉義反斜杠,從最左側的所有字符之前,這種'#'通過行末尾將被忽略。
這意味着兩個以下正則表達式匹配的對象,一個十進制數是相同的功能:
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)
-
掃描字符串,尋找的第一個由該正則表達式模式產生匹配的位置,並返回相應的MatchObject實例。返回None如果沒有字符串中的位置匹配模式 ;請注意這不同於在字符串的某個位置中找到一個長度為零的匹配。
- re.match(pattern, string, flags=0)
如果在字符串的開頭的零個或更多字符匹配正則表達式模式,將返回相應的MatchObject實例。返回None則該字符串中與模式不匹配;請注意這是不同於零長度匹配。
請注意,即使在多行模式下, re.match()將只匹配字符串的開頭,而不是在每個行的開頭。
如果你想要在字符串中的任意位置定位一個匹配,改用search () (請參見search () 與 match ())。
re.fullmatch(pattern, string, flags=0)
-
如果整個字符串匹配正則表達式模式,則返回一個match對象。如果字符串與模式不匹配,則返回None;請注意:這與長度為0的match是有區別的。
新版本3.4
- re.split(pattern, string, maxsplit=0, flags=0)
-
將字符串拆分的模式的匹配項。如果在模式中使用捕獲括號,則然后也作為結果列表的一部分返回的文本模式中的所有組。如果maxsplit不為零,頂多maxsplit分裂發生,並且該字符串的其余部分將作為列表的最后一個元素返回。(不兼容性說明: 在原始的 Python 1.5 版本中, maxsplit被忽略。這已被固定在以后的版本。)
>>> 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']
如果在分離器有捕獲組,它匹配字符串的開頭,結果將啟動與空字符串。同樣對於字符串的末尾:
>>> re.split('(\W+)', '...words, words...') ['', '...', 'words', ', ', 'words', '...', '']
這樣一來,分離器組件始終都位於相同的相對索引在結果列表中 (例如,如果有是在分離器,在 0,第二個捕獲組等等)。
請注意,拆分將永遠不會拆分對空模式匹配的字符串。舉個例子:
>>> re.split('x*', 'foo') ['foo'] >>> re.split("(?m)^$", "foo\n\nbar\n") ['foo\n\nbar\n']
2.7 版本中的更改:添加可選的標志參數。
- re.findall(pattern, string, flags=0)
-
作為一個字符串列表,在字符串中,返回所有非重疊匹配的模式。該字符串是從左到右掃描的,匹配按照發現的順序返回。如果一個或多個組是本模式中,返回一個列表的群體 ;如果該模式具有多個組,這將是元組的列表。空匹配包含在結果中,除非他們接觸到另一場匹配的開頭。
在 1.5.2 版本新。
2.4 版本中的更改:添加可選的標志參數。
- re.finditer(pattern, string, flags=0)
-
返回一個迭代器符合MatchObject情況 在 RE模式字符串中的所有非重疊的匹配。該字符串是掃描的左到右,和按發現的順序返回匹配。空匹配包含在結果中,除非他們接觸的另一個匹配的開頭。
新版本 2.2 中的。
2.4 版本中的更改:添加可選的標志參數。
- re.sub(pattern, repl, string, count=0, flags=0)
-
Return the string obtained by replacing the leftmost non-overlapping occurrences of pattern in string by the replacement repl. 如果pattern沒有被找到, string不變。repl 可以是一個字符串或一個函數;如果是一個字符串, 任何反斜杠轉義都會實現。那就是,\n會轉化成一個換行符,\r 會轉化成一個回車,等等。 未知的轉義字符例如 \j不做處理。Backreferences, such as \6, are replaced with the substring matched by group 6 in the pattern. For example:
>>> 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是一個函數,它被呼吁每個非重疊模式發生。該函數采用單個匹配對象作為參數,並返回替換字符串。舉個例子:
>>> 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'
模式可以是一個字符串或重新對象。
可選參數計數是模式出現,要更換 ; 的最大次數計數必須為非負整數。如果省略或為零,所有事件將被替換。空匹配模式取代只有當不毗鄰前一個匹配,所以子 ('x *' '-', 'abc')返回'-a-b-c-'。
In string-type repl arguments, in addition to the character escapes and backreferences described above, \g<name> will use the substring matched by the group named name, as defined by the (?P<name>...) syntax. \g<number> uses the corresponding group number; \g<2> is therefore equivalent to \2, but isn’t ambiguous in a replacement such as \g<2>0. \20 would be interpreted as a reference to group 20, not a reference to group 2 followed by the literal character '0'. The backreference \g<0> substitutes in the entire substring matched by the RE.
2.7 版本中的更改:添加可選的標志參數。
- re.subn(pattern, repl, string, count=0, flags=0)
-
執行相同的操作,如sub(),但返回一個元組(new_string, number_of_subs_made)。
2.7 版本中的更改:添加可選的標志參數。
- re.escape(string)
-
返回的字符串與所有非字母數字帶有反斜杠 ;這是有用的如果你想匹配一個任意的文本字符串,在它可能包含正則表達式元字符。
- re.purge()
-
清除正則表達式緩存。
- exception re.error
-
當一個字符串傳遞給這里的函數之一時引發的異常不是有效的正則表達式 (例如,它可能包含不匹配的括號) 或其他一些錯誤在編譯或匹配過程中發生的時。如果一個字符串包含不匹配的一種模式,它永遠不會是一個錯誤。
1.3. Regular Expression Objects
- class re.RegexObject
-
編譯的正則表達式對象支持以下方法和屬性:
- search(string[, pos[, endpos]])
-
掃描字符串尋找一個位置,在此正則表達式產生的匹配,並返回相應的作法實例。返回無如果沒有字符串中的位置匹配模式 ;請注意這是不同於找到一個長度為零的匹配在一些點在字符串中。
可選的第二個參數pos給索引在字符串中搜索在哪里開始 ;它將默認為0。這並不完全等於切片的字符串 ; ' ^'模式字符匹配在真正開始的字符串和位置剛換行,但不是一定是在開始搜索的索引。
可選參數endpos限制了多遠的字符串將被搜索 ;它將,如果字符串是endpos個字符長,因此,只有從pos到字符endpos - 1將搜索匹配項。如果endpos小於pos,沒有比賽會發現,否則,如果rx是已編譯的正則表達式對象, rx.search (字符串, 0, 50)相當於rx.search (字符串 [: 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]])
如果在字符串的開頭的零個或更多字符匹配這個正則表達式,將返回相應的作法實例。返回沒有如果,則該字符串與模式不匹配請注意這是不同於零長度匹配。
可選pos和endpos參數具有相同的含義,至於search ()方法。
>>> 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 ...>
如果你想要在字符串中的任意位置找到一個匹配,改用search() (請參見search() 與 match())。
- fullmatch(string[, pos[, endpos]])
-
如果整個字符串匹配正則表達式模式,則返回一個match對象。如果字符串與模式不匹配,則返回None;請注意:這與長度為0的match是有區別的。
新版本3.4
>>> pattern = re.compile("o[gh]") >>> pattern.fullmatch("dog") # No match as "o" is not at the start of "dog". >>> pattern.fullmatch("ogre") # No match as not the full string matches. >>> pattern.fullmatch("doggie", 1, 3) # Matches within given limits. <_sre.SRE_Match object; span=(1, 3), match='og'>
- split(string, maxsplit=0)
-
與使用編譯的模式的split ()函數相同。
- finditer(string[, pos[, endpos]])
-
類似於finditer()的功能,使用編譯后的模式,但也接受可選的pos和endpos參數限制搜索區域像match()。
- sub(repl, string, count=0)
-
使用編譯的模式的sub()函數完全相同。
- subn(repl, string, count=0)
-
使用編譯的模式的subn()函數完全相同。
- flags
-
正則表達式匹配的標志。這是給compile()和任何標志的組合(嗎?...)模式中的內聯標志。
- groups
-
捕獲模式中的組數。
- groupindex
-
一本字典,由定義任何符號組名稱映射(?P < id >)組號碼。這本詞典是空的如果在模式中使用了無符號的組。
- pattern
-
模式字符串中從中重新對象的編譯。
1.4. Match Objects
- class re.MatchObject
-
Match 對象始終有一個為 True 的布爾值。因為 match() 和 search() 返回 None 如果不匹配的話,您可以測試是否符合簡單 if 的語句:
match = re.search(pattern, string) if match: process(match)
Match 對象支持下列方法和屬性:
- expand(template)
-
Return the string obtained by doing backslash substitution on the template string template, as done by the sub() method. Escapes such as\n are converted to the appropriate characters, and numeric backreferences (\1, \2) and named backreferences (\g<1>, \g<name>) are replaced by the contents of the corresponding group.
- group([group1, ...])
-
返回Match對象的一個或多個子組。如果單個參數,結果是一個單一的字符串 ;如果有多個參數,其結果是參數每一項的元組。如果沒有參數, group1默認為零 (整場比賽返回)。如果groupN參數為零,相應的返回值是整個匹配的字符串 ;如果它是在具有包容性的范圍 [1..99],它是模式進行相應的括號組匹配的字符串。如果組編號是負值或大於在模式中定義的組的數目,被引發IndexError異常。如果一組包含在模式不匹配的一部分中,相應的結果是沒有。如果一組包含在模式匹配多次的一部分,則返回最后一場比賽。
>>> 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')
如果正則表達式使用(?P < 名稱 >...) 語法, groupN參數也可能查明群體按他們的通訊組名稱的字符串。如果字符串參數不用作模式中的組名稱,被引發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'
通過它們的索引還可以獲取到已命名的組:
>>> m.group(1) 'Malcolm' >>> m.group(2) 'Reynolds'
如果一組匹配多次,只有最后一個匹配可訪問:
>>> m = re.match(r"(..)+", "a1b2c3") # Matches 3 times. >>> m.group(1) # Returns only the last match. 'c3'
- groups([default])
-
返回包含所有匹配到的子組的元組, 從1到模式中的所有組。默認實參用於團體沒有參加這場比賽 ;它將默認為None。(不兼容性說明: 在原始的 Python 1.5 版本中,如果元組是一個元素長,字符串將返回相反。在以后的版本 (從 1.5.1 對),單身人士返回元組在這種情況下)。
舉個例子:
>>> m = re.match(r"(\d+)\.(\d+)", "24.1632") >>> m.groups() ('24', '1632')
如果我們使小數點和一切在它以后可選,並不是所有的組可能會參加比賽。這些團體將默認為無,除非給出了默認參數:
>>> 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])
-
返回一個包含所有的比賽,由子組名稱鍵控的命名子群的字典。默認實參用於團體沒有參加這場比賽 ;它將默認為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])
-
返回的開始和結束的由組; 匹配的子字符串的索引組的默認值為零 (即整個匹配的子字符串)。如果組存在,但卻無助於這場比賽將返回-1 。對於一個匹配對象m和做貢獻匹配的組g ,由組g (相當於m.group(g)) 匹配的子字符串是
m.string[m.start(g):m.end(g)]
請注意, m.start(group)將等於m.end(group) ,是否組匹配空字符串。例如后, m = re.search('b(c?)', 'cba')、 m.start(0)是 1、 m.end(0)是 2, m.start(1)和m.end(1)是兩個 2 和m.start(2)引發IndexError異常。
將刪除的電子郵件地址remove_this的示例:
>>> email = "tony@tiremove_thisger.net" >>> m = re.search("remove_this", email) >>> email[:m.start()] + email[m.end():] 'tony@tiger.net'
- span([group])
-
作法 m,對於返回 2 元組(m.start(group), m.end(group))。請注意是否組不會助長這場比賽,這是(-1, -1)。組的默認值為零,整場比賽。
- lastindex
-
最后的整數索引匹配捕獲組,或沒有,如果沒有組均在所有匹配。例如,表達式(a) b, ((a)(b)),並且((ab))將有lastindex = = 1如果應用於字符串ab,同時表達(a)(b)將有lastindex = = 2,如果應用到相同的字符串。
- lastgroup
-
最后一次的名稱匹配捕獲的組,或沒有如果小組不是有一個名稱,或者如果沒有組均在所有匹配。
1.5. Examples
1.5.1. 檢查對子
在這個例子中,我們將使用下面的 helper 函數去更優雅地顯示 match 對象:
def displaymatch(match): if match is None: return None return '<Match: %r, groups=%r>' % (match.group(), match.groups())
假設您要編寫一個球員手為 5 個字符的字符串代表與代表一張卡,每個字符的撲克程序"a"ace、"k"為國王、 王后、 傑克的"j"、"t"為 10,"q"和"2"至"9"代表卡具有此值。
若想查看給定字符串是否為一手有效牌的話,可履行以下操作:
>>> 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=()>"
That last hand, "727ak", contained a pair, or two of the same valued cards. 若想以正則表達式匹配它的話,可使用如下反向引用:
>>> 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',)>"
要找出對包括什么卡,一個可以以下列方式使用group的作法() 方法:
>>> pair.match("717ak").group(1) '7' # Error because re.match() returns None, which doesn't have a group() method: >>> pair.match("718ak").group(1) Traceback (most recent call last): File "<pyshell#23>", line 1, in <module> re.match(r".*(.).*\1", "718ak").group(1) AttributeError: 'NoneType' object has no attribute 'group' >>> pair.match("354aa").group(1) 'a'
1.5.2. 模擬 scanf() 函數
Python 目前沒有相當於scanf()。正則表達式是一般功能更強大,但也更加冗長,比scanf()的格式字符串。下表提供了一些多或少scanf()格式標記和正則表達式之間的等價映射。
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-7]+ |
%s | \S+ |
%u | \d+ |
%x, %X | [-+]?(0[xX])?[\dA-Fa-f]+ |
若想從下述字符串提取文件名和數字
/usr/sbin/sendmail - 0 errors, 4 warnings
您將使用如下的 scanf() 格式
%s - %d errors, %d warnings
等價的正則表達式為
(\S+) - (\d+) errors, (\d+) warnings
1.5.3. search() vs. match()
Python 提供了兩種不同的原始操作基於正則表達式: re.match()檢查是否只在字符串的開頭匹配而re.search()檢查是否在任何地方 (這是默認情況下,Perl 做的) 的字符串匹配。
舉個例子:
>>> re.match("c", "abcdef") # No match >>> re.search("c", "abcdef") # Match <_sre.SRE_Match object at ...>
正則表達式開頭' ^'可以用與search ()來限制進行匹配字符串的開頭(“^”表示匹配字符串的開頭):
>>> re.match("c", "abcdef") # No match >>> re.search("^c", "abcdef") # No match >>> re.search("^a", "abcdef") # Match <_sre.SRE_Match object at ...>
但是請注意在多行模式match ()只匹配字符串的開頭而使用一個正則表達式開頭的search () ' ^'將匹配每行開頭。
>>> re.match('X', 'A\nB\nX', re.MULTILINE) # No match >>> re.search('^X', 'A\nB\nX', re.MULTILINE) # Match <_sre.SRE_Match object at ...>
1.5.4. 制作一個電話本
split ()將字符串拆分為傳遞模式由分隔的列表。該方法是將文本數據轉換為數據結構,可以輕松地閱讀和修改由 Python 作為顯示在下面的示例創建一個電話簿非常寶貴。
首先,這里是輸入。通常它可能來自一個文件,在這里我們使用的三重引號的字符串語法:
>>> 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"""
由一個或多個換行符分隔條目。現在我們轉換字符串到一個列表中的每個非空的行,有它自己的條目:
>>> 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']
最后,拆分到一個列表中的第一個名字、 姓氏、 電話號碼和地址的每個條目。因為地址中有空格,我們劈裂的形態,在里面,我們使用maxsplit參數的split () :
>>> [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']]
:?模式匹配在冒號之后的最后一個名稱,以便它不出現在結果列表中。與4 maxsplit ,我們可以分開的街道名稱門牌號碼:
>>> [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']]
1.5.5. Text Munging
sub()替換字符串或函數的結果為每次出現的一種模式。此示例演示如何使用sub()具有功能"偽裝"的文本,或隨機中每個單詞的句子除第一個和最后一個字符之外的所有字符的順序:
>>> 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.'
1.5.6. 查找所有副詞
search ()一樣, findall()匹配所有出現的一種模式,而不僅僅是第一個。舉個例子,如果你是一位作家,並且想要尋找一些文本中的副詞所有,他或她可能會使用findall()以下列方式:
>>> text = "He was carefully disguised but captured quickly by police." >>> re.findall(r"\w+ly", text) ['carefully', 'quickly']
1.5.7. 查找所有副詞和它們的位置
如果你想比匹配的文本模式的所有匹配項有關詳細信息, finditer()是有用的因為它提供的作法的實例,而不是字符串。繼續前面的示例中,如果其中一個是一位想要找到所有的副詞和他們的位置在一些文字作家,他或她會使用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
1.5.8. Raw 字符串表示法
Raw string notation (r"text") keeps regular expressions sane. Without it, every backslash ('\') in a regular expression would have to be prefixed with another one to escape it. For example, the two following lines of code are functionally identical:
>>> re.match(r"\W(.)\1\W", " ff ") <_sre.SRE_Match object at ...> >>> re.match("\\W(.)\\1\\W", " ff ") <_sre.SRE_Match object at ...>
當想要匹配文字反斜杠時,必須在正則表達式中先轉義。With raw string notation, this means r"\\". Without raw string notation, one must use "\\\\", making the following lines of code functionally identical:
>>> re.match(r"\\", r"\\") <_sre.SRE_Match object at ...> >>> re.match("\\\\", r"\\") <_sre.SRE_Match object at ...>