2019独角兽企业重金招聘Python工程师标准>>>
1、字符匹配 大多数字母和字符一般都会和自身匹配。例如,正则表达式 test 会和字符串“test”完全匹配。( 这里有一个元字符的完整列表;其含义会在本指南余下部分进行讨论。
. ^ $ * + ? { [ ] \ | ( )
我们首先考察的元字符是"[" 和 "]"。字符可以单个列出,也可以用“-”号分隔的两个给定字符来表示一个字符区间。例如,[abc] 将匹配"a", "b", 或 "c"中的任意一个字符;也可以用区间[a-c]来表示同一字符集,和前者效果一致。如果你只想匹配小写字母,那么 RE 应写成 [a-z].
元字符在类别里并不起作用。例如,[akm$]将匹配字符"a", "k", "m", 或 "$" 中的任意一个;"
其做法是把"^"作为类别的首个字符;其它地方的"^"只会简单匹配 "^"字符本身。例如,[^5] 将匹配除 "5" 之外的任意字符。
做为 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_]。
"." 通常被用于你想匹配“任何字符”的地方。
2、重复
ca*t 将匹配 "ct" (0 个 "a" 字符), "cat" (1 个 "a"), "caaat" (3 个 "a" 字符)等等。RE 引擎有各种来自 C 的整数类型大小的内部限制,以防止它匹配超过20亿个 "a" 字符;你也许没有足够的内存去建造那么大的字符串,所以将不会累计到那个限制。
另一个重复元字符是 +,表示匹配一或更多次。请注意 * 和 + 之间的不同;* 匹配零或更多次,所以可以根本就不出现,而 + 则要求至少出现一次。用同一个例子,ca+t 就可以匹配 "cat" (1 个 "a"), "caaat" (3 个 "a"), 但不能匹配 "ct"。
还有更多的限定符。问号 ? 匹配一次或零次;你可以认为它用于标识某事物是可选的。例如:home-?brew 匹配 "homebrew" 或 "home-brew"。
最复杂的重复限定符是 {m,n},其中 m 和 n 是十进制整数。该限定符的意思是至少有 m 个重复,至多到 n 个重复。举个例子,a/{1,3}b 将匹配 "a/b","a//b" 和 "a///b"。它不能匹配 "ab" 因为没有斜杠,也不能匹配 "ab" ,因为有四个。
3、编译正则表达式 正则表达式被编译成 RegexObject
实例,可以为不同的操作提供方法,如模式匹配搜索或字符串替换。
#!python
import re
p = re.compile('ab*')
print p
<_sre.SRE_Pattern object at 0xb76e1a70>
反斜杠的麻烦 在早期规定中,正则表达式用反斜杠字符 ("") 来表示特殊格式或允许使用特殊字符而不调用它的特殊用法。这就与 Python 在字符串中的那些起相同作用的相同字符产生了冲突。
让我们举例说明,你想写一个 RE 以匹配字符串 "\section",可能是在一个 LATEX 文件查找。为了要在程序代码中判断,首先要写出想要匹配的字符串。接下来你需要在所有反斜杠和其它元字符前加反斜杠来取消其特殊意义,结果要匹配的字符串就成了"\section"。 当把这个字符串传递给re.compile()时必须还是"\section"。然而,作为Python的字符串实值(string literals)来表示的话,"\section"中两个反斜杠还要再次取消特殊意义,最后结果就变成了"\\section"。
字符 阶段
\section 要匹配的字符串
\section 为 re.compile 取消反斜杠的特殊意义
"\\section" 为"\section"的字符串实值(string literals)取消反斜杠的特殊意义
简单地说,为了匹配一个反斜杠,不得不在 RE 字符串中写 '\\',因为正则表达式中必须是 "\",而每个反斜杠在常规的 Python 字符串实值中必须表示成 "\"。在 REs 中反斜杠的这个重复特性会导致大量重复的反斜杠,而且所生成的字符串也很难懂。
解决的办法就是为正则表达式使用 Python 的 raw 字符串表示;在字符串前加个 "r" 反斜杠就不会被任何特殊方式处理,所以 r"\n" 就是包含"" 和 "n" 的两个字符,而 "\n" 则是一个字符,表示一个换行。正则表达式通常在 Python 代码中都是用这种 raw 字符串表示。
常规字符串 Raw 字符串
"ab*" r"ab*"
"\\section" r"\section"
"\w+\s+\1" r"\w+\s+\1"
4、执行匹配
方法/属性 作用
match() 决定 RE 是否在字符串刚开始的位置匹配
search() 扫描字符串,找到这个 RE 匹配的位置
findall() 找到 RE 匹配的所有子串,并把它们作为一个列表返回
finditer() 找到 RE 匹配的所有子串,并把它们作为一个迭代器返回
如果没有匹配到的话,match() 和 search() 将返回 None。如果成功的话,就会返回一个 MatchObject
实例,其中有这次匹配的信息:它是从哪里开始和结束,它所匹配的子串等等。