Python基础篇【第十篇】:正则表达式
Python正则表达式
正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配。
Python 自1.5版本起增加了re 模块,它提供 Perl 风格的正则表达式模式。
re 模块使 Python 语言拥有全部的正则表达式功能。
compile 函数根据一个模式字符串和可选的标志参数生成一个正则表达式对象。该对象拥有一系列方法用于正则表达式匹配和替换。
re 模块也提供了与这些方法功能完全一致的函数,这些函数使用一个模式字符串做为它们的第一个参数。
本章节主要介绍Python中常用的正则表达式处理函数。
基本的正则表达式:
#!/usr/bin/env python3 import re # 1,字符匹配(普通字符,元字符) # 普通字符:大多数字符和字母都会和自身匹配 ret = re.findall('alex','yuanaleSxalexwupeiqi') #匹配普通字符 print(ret) # 1,元字符: . ^ $ * + ? {} [] () \ # # 元字符是[" 和 "].常用来指定一个字符类别,字符类别就是指你想匹配的一个字符集.字符可以单个列出,也可以用"-"号分分隔的两个给定字符来表示 # 一个 # 字符区间. ret = re.findall("[a-c]","abcd") print(ret) # 元字符在类别里并不起作用.例如:[akm$]将匹配字符"a","k", "m", 或 "$" 中的任意一个;"$"通常用作元字符,但在字符类别里,其特性被除去, # 恢复成普通字符。 ret = re.search("\d+","abc3333").group() print(ret) ret = re.search("[\d+]","abc3333").group() print(ret) # []:元字符[]表示字符类,在一个字符类中,只有字符^ - ]和\有特殊意义. # 字符\仍然表示转义,字符-可以定义字符的范围,字符^放在前面,表示非. # 也许最重要的元字符是反斜杠"\"。 做为 Python 中的字符串字母,反斜杠後面可以加不同的字符以表示不同特殊意义。它也可以用于取消所有的元字符,这样你就可以在模式中匹配它们了。举个例子,如果你需要匹配字符 "[" 或 "\",你可以在它们之前用反斜杠来取消它们的特殊意义: \[ 或 \\。 ''' \d 匹配任何十进制数;它相当于类 [0-9]。 \D 匹配任何非数字字符;它相当于类 [^0-9]。 \s 匹配任何空白字符;它相当于类 [ \t\n\r\f\v]。 \S 匹配任何非空白字符;它相当于类 [^ \t\n\r\f\v]。 \w 匹配任何字母数字字符;它相当于类 [a-zA-Z0-9_]。 \W 匹配任何非字母数字字符;它相当于类 [^a-zA-Z0-9_]。 ''' # 这样特殊字符都可以包含在一个字符类中。如,[\s,.]字符类将匹配任何空白字符或","或"."。 # 元字符 . 匹配除了换行字符外的任何字符,在 alternate 模式(re.DOTALL)下它甚至可以匹配换行。"." 通常被用于你想匹配“任何字符”的地方。 # 重复 # 指定正则表达式的一部分的重复次数. # 重复元字符*号,*并不是匹配字符"*";相反,它指定前一个字符可以被匹配零次或更多次,而不是只有一次。 ret = re.search("ca*t","cat").group() print(ret) ret = re.search("ca*t","caaaaat").group() print(ret) # 像*这样的重复是"贪婪的",当重复一个RE时,匹配引擎会尝试重复尽多可能多的次数,如果模式的后面没有被匹配,匹配引擎将回退并在次尝试更小的重复. ret = re.search("a[bcd]*b","abcbd").group() print(ret) # 另一个重复元字符是 +,表示匹配一或更多次。请注意 * 和 + 之间的不同;*匹配零或更多次,所以根本就可以不出现,而 + 则要求至少出现一次。 # 问号 ? 匹配一次或零次;你可以认为它用于标识某事物是可选的。例如:home-?brew 匹配 "homebrew" 或 "home-brew"。 ret = re.search("home-?brew","home-brew").group() print(ret) # 最复杂的重复限定符是 {m,n},其中 m 和 n 是十进制整数。该限定符的意思是至少有 m 个重复,至多到 n 个重复。 ret = re.search("a/{1,3}b","a///b").group() print(ret) # 将匹配 "a/b","a//b" 和 "a///b"。它不能匹配 "ab" 因为没有斜杠,也不能匹配 "a////b" ,因为有四个。 # 最复杂的重复限定符是 {m,n},其中 m 和 n 是十进制整数。该限定符的意思是至少有 m 个重复,至多到 n 个重复。举个例子,a/{1,3}b 将匹配 "a/b","a//b" 和 "a///b"。它不能匹配 "ab" 因为没有斜杠,也不能匹配 "a////b" ,因为有四个。你可以忽略 m 或 n;因为会为缺失的值假设一个合理的值。忽略 m 会认为下边界是 0,而忽略 n 的结果将是上边界为无穷大 -- 实际上是先前我们提到的 2 兆,但这也许同无穷大一样。 # {0,} 等同于 *,{1,} 等同于 +,而{0,1}则与 ? 相同。如果可以的话,最好使用 *,+,或?。很简单因为它们更短也再容易懂。 # 反斜杠 # 在早期规定中,正则表达式用反斜杠字符 (""") 来表示特殊格式或允许使用特殊字符而不调用它的特殊用法。这就与 Python 在字符串中的那些起相同作用的相同字符产生了冲突。 # 解决的办法就是为正则表达式使用 Python 的 raw 字符串表示;在字符串前加个 "r" 反斜杠就不会被任何特殊方式处理,所以 r"\n" 就是包含"\" 和 "n" 的两个字符,而 "\n" 则是一个字符,表示一个换行。正则表达式通常在 Python 代码中都是用这种 raw 字符串表示。 # 执行匹配 ''' match() 决定RE是否在字符串刚开始的位置匹配 search() 扫描字符串,找到这个RE匹配的位置 findall() 找打RE匹配的所有子串,并把他们作为一个列表返回 finditer() 找到RE匹配的所有子串,并把他们作为一个迭代器返回 ''' # 如果没有匹配到的话,match() 和 search() 将返回 None。如果成功的话,就会返回一个 `MatchObject` 实例,其中有这次匹配的信息:它是从哪里开始和结束,它所匹配的子串等等。 p = re.compile('[a-z]+') ret = p.match("") ret1 = p.match("tempo") g = ret1.group() s = ret1.start(),ret1.end() m = ret1.span() print(ret,ret1,g,s,m) ''' group() 返回被RE匹配的字符串 start() 返回匹配开始的位置 end() 返回匹配结束的位置 span() 返回一个元组包含匹配(开始,结束)的位置 ''' # group() 返回 RE 匹配的子串。start() 和 end() 返回匹配开始和结束时的索引。span() 则用单个元组把开始和结束时的索引一起返回。因为匹配方法检查到如果 RE 在字符串开始处开始匹配,那么 start() 将总是为零。
修饰符:
修饰符 描述 re.I 使匹配对大小写不敏感 re.L 做本地化识别(locale-aware)匹配 re.M 多行匹配,影响 ^ 和 $ re.S 使 . 匹配包括换行在内的所有字符 re.U 根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B. re.X 该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。
正则表达式模式:
模式 | 描述 |
---|---|
^ | 匹配字符串的开头 |
$ | 匹配字符串的末尾。 |
. | 匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符。 |
[...] | 用来表示一组字符,单独列出:[amk] 匹配 'a','m'或'k' |
[^...] | 不在[]中的字符:[^abc] 匹配除了a,b,c之外的字符。 |
re* | 匹配0个或多个的表达式。 |
re+ | 匹配1个或多个的表达式。 |
re? | 匹配0个或1个由前面的正则表达式定义的片段,非贪婪方式 |
re{ n} | |
re{ n,} | 精确匹配n个前面表达式。 |
re{ n, m} | 匹配 n 到 m 次由前面的正则表达式定义的片段,贪婪方式 |
a| b | 匹配a或b |
(re) | G匹配括号内的表达式,也表示一个组 |
(?imx) | 正则表达式包含三种可选标志:i, m, 或 x 。只影响括号中的区域。 |
(?-imx) | 正则表达式关闭 i, m, 或 x 可选标志。只影响括号中的区域。 |
(?: re) | 类似 (...), 但是不表示一个组 |
(?imx: re) | 在括号中使用i, m, 或 x 可选标志 |
(?-imx: re) | 在括号中不使用i, m, 或 x 可选标志 |
(?#...) | 注释. |
(?= re) | 前向肯定界定符。如果所含正则表达式,以 ... 表示,在当前位置成功匹配时成功,否则失败。但一旦所含表达式已经尝试,匹配引擎根本没有提高;模式的剩余部分还要尝试界定符的右边。 |
(?! re) | 前向否定界定符。与肯定界定符相反;当所含表达式不能在字符串当前位置匹配时成功 |
(?> re) | 匹配的独立模式,省去回溯。 |
\w | 匹配字母数字 |
\W | 匹配非字母数字 |
\s | 匹配任意空白字符,等价于 [\t\n\r\f]. |
\S | 匹配任意非空字符 |
\d | 匹配任意数字,等价于 [0-9]. |
\D | 匹配任意非数字 |
\A | 匹配字符串开始 |
\Z | 匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串。c |
\z | 匹配字符串结束 |
\G | 匹配最后匹配完成的位置。 |
\b | 匹配一个单词边界,也就是指单词和空格间的位置。例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。 |
\B | 匹配非单词边界。'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。 |
\n, \t, 等. | 匹配一个换行符。匹配一个制表符。等 |
\1...\9 | 匹配第n个分组的子表达式。 |
\10 | 匹配第n个分组的子表达式,如果它经匹配。否则指的是八进制字符码的表达式。 |
正则表达式实例
字符匹配
实例 | 描述 |
---|---|
python | 匹配 "python". |
字符类
实例 | 描述 |
---|---|
[Pp]ython | 匹配 "Python" 或 "python" |
rub[ye] | 匹配 "ruby" 或 "rube" |
[aeiou] | 匹配中括号内的任意一个字母 |
[0-9] | 匹配任何数字。类似于 [0123456789] |
[a-z] | 匹配任何小写字母 |
[A-Z] | 匹配任何大写字母 |
[a-zA-Z0-9] | 匹配任何字母及数字 |
[^aeiou] | 除了aeiou字母以外的所有字符 |
[^0-9] | 匹配除了数字外的字符 |
特殊字符类
实例 | 描述 |
---|---|
. | 匹配除 "\n" 之外的任何单个字符。要匹配包括 '\n' 在内的任何字符,请使用象 '[.\n]' 的模式。 |
\d | 匹配一个数字字符。等价于 [0-9]。 |
\D | 匹配一个非数字字符。等价于 [^0-9]。 |
\s | 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。 |
\S | 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。 |
\w | 匹配包括下划线的任何单词字符。等价于'[A-Za-z0-9_]'。 |
\W | 匹配任何非单词字符。等价于 '[^A-Za-z0-9_]'。 |