Python 正则表达式
正则表达式 (Regular Expression) 又称 RegEx, 是用来匹配字符的一种工具. 在一大串字符中寻找你需要的内容. 它常被用在很多方面, 比如网页爬虫, 文稿整理, 数据筛选等等.
比如我需要爬取网页中每一页的标题. 而网页中的标题常常是这种形式:
<title>我是标题</ title>
而且每个网页的标题各不相同, 我就能使用正则表达式, 用一种简单的匹配方法, 一次性选取出成千上万网页的标题信息.
正则表达式无非就是在做这么一回事. 在文字中找到特定的内容, 比如下面的内容.我们在 “dog runs to cat” 这句话中寻找是否存在 “cat” 或者 “bird”,先使用成员运算符方式进行匹配,若要使用正则表达式, 首先需要调用一个 python 的内置模块 re,可以看出, 如果 re.search() 找到了结果, 它会返回一个match 的 object. 如果没有匹配到, 它会返回 None.
import re pattern1='cat' pattern2='bird' string='dog runs to cat.' #成员运算符方式匹配 print(pattern1 in string) print(pattern2 in string) #正则表达式匹配 print(re.search(pattern1,string)) print(re.search(pattern2,string))
运行结果:
True
False
<_sre.SRE_Match object; span=(12, 15), match='cat'>
None
除了上面的简单匹配, 下面的内容才是正则的核心内容, 使用特殊的 pattern 来灵活匹配需要找的文字.如果需要找到潜在的多个可能性文字, 我们可以使用 [] 将可能的字符囊括进来. 比如 [ab] 就说明我想要找的字符可以是 a 也可以是 b,不能是ab. 这里我们还需要注意的是, 建立一个正则的规则, 我们在 pattern 的 “” 前面需要加上一个 r 用来表示这是正则表达式, 而不是普通字符串. 通过下面这种形式, 如果字符串中出现 “run” 或者是“ran”, 它都能找到.
import re x=r'r[ua]n' print(re.search(x,string))
运行结果:
<_sre.SRE_Match object; span=(4, 7), match='run'>
同样, 中括号 [] 中还可以是以下这些或者是这些的组合. 比如 [A-Z] 表示的就是所有大写的英文字母. [0-9a-z] 表示可以是数字也可以是任何小写字母.
import re print(re.search(r"r[A-Z]n", "dog runs to cat")) # None print(re.search(r"r[a-z]n", "dog runs to cat")) # <_sre.SRE_Match object; span=(4, 7),match='run'> print(re.search(r"r[0-9]n", "dog r2ns to cat")) # <_sre.SRE_Match object; span=(4, 7),match='r2n'> print(re.search(r"r[0-9a-z]n", "dog runs to cat")) # <_sre.SRE_Match object; span=(4, 7),match='run'>
执行结果:
None
<_sre.SRE_Match object; span=(4, 7), match='run'>
<_sre.SRE_Match object; span=(4, 7), match='r2n'>
<_sre.SRE_Match object; span=(4, 7), match='run'>
除了自己定义规则, 还有很多匹配的规则时提前就给你定义好了的. 下面有一些特殊的匹配类型给大家先总结一下, 然后再上一些例子.
\d : 任何数字
\D : 不是数字
\s : 任何 white space, 如 [\t\n\r\f\v]
\S : 不是 white space
\w : 任何大小写字母, 数字和 “” [a-zA-Z0-9]
\W : 不是 \w
\b : 空白字符 (只在某个字的开头或结尾)
\B : 空白字符 (不在某个字的开头或结尾)
\\ : 匹配 \
. : 匹配任何字符 (除了 \n)
^ : 匹配开头
$ : 匹配结尾
? : 前面的字符可有可无
import re print(re.search(r"r\dn", "run r4n")) # <_sre.SRE_Match object; span=(4, 7), match='r4n'> print(re.search(r"r\Dn", "run r4n")) # <_sre.SRE_Match object; span=(0, 3), match='run'> print(re.search(r"r\sn", "r\nn r4n")) # <_sre.SRE_Match object; span=(0, 3), match='r\nn'> print(re.search(r"r\Sn", "r\nn r4n")) # <_sre.SRE_Match object; span=(4, 7), match='r4n'> print(re.search(r"r\wn", "r\nn r4n")) # <_sre.SRE_Match object; span=(4, 7), match='r4n'> print(re.search(r"r\Wn", "r\nn r4n")) # <_sre.SRE_Match object; span=(0, 3), match='r\nn'> print(re.search(r"\bruns\b", "dog runs to cat")) # <_sre.SRE_Match object; span=(4, 8), match='runs'> print(re.search(r"\B runs \B", "dog runs to cat")) # <_sre.SRE_Match object; span=(8, 14), match=' runs '> print(re.search(r"runs\\", "runs\ to me")) # <_sre.SRE_Match object; span=(0, 5), match='runs\\'> print(re.search(r"r.n", "r[ns to me")) # <_sre.SRE_Match object; span=(0, 3), match='r[n'> print(re.search(r"^dog", "dog runs to cat")) # <_sre.SRE_Match object; span=(0, 3), match='dog'> print(re.search(r"cat$", "dog runs to cat")) # <_sre.SRE_Match object; span=(12, 15), match='cat'> print(re.search(r"Mon(day)?", "Monday")) # <_sre.SRE_Match object; span=(0, 6), match='Monday'> print(re.search(r"Mon(day)?", "Mon")) # <_sre.SRE_Match object; span=(0, 3), match='Mon'>
程序执行结果:
<_sre.SRE_Match object; span=(4, 7), match='r4n'>
<_sre.SRE_Match object; span=(0, 3), match='run'>
<_sre.SRE_Match object; span=(0, 3), match='r\nn'>
<_sre.SRE_Match object; span=(4, 7), match='r4n'>
<_sre.SRE_Match object; span=(4, 7), match='r4n'>
<_sre.SRE_Match object; span=(0, 3), match='r\nn'>
<_sre.SRE_Match object; span=(4, 8), match='runs'>
None
<_sre.SRE_Match object; span=(0, 5), match='runs\\'>
<_sre.SRE_Match object; span=(0, 3), match='r[n'>
<_sre.SRE_Match object; span=(0, 3), match='dog'>
<_sre.SRE_Match object; span=(12, 15), match='cat'>
<_sre.SRE_Match object; span=(0, 6), match='Monday'>
<_sre.SRE_Match object; span=(0, 3), match='Mon'>
如果一个字符串有很多行, 我们想使用 ^ 形式来匹配行开头的字符, 如果用通常的形式是不成功的. 比如下面的 “I” 出现在第二行开头, 但是使用 r"^I" 却匹配不到第二行, 这时候, 我们要使用 另外一个参数, 让 re.search() 可以对每一行单独处理.这个参数就是 flags=re.M, 或者这样写也行 flags=re.MULTILINE.
import re string = """a dog runs to snake. I run to cat. """ print(re.search(r'^I',string))# None print(re.search(r"^I", string, flags=re.M)) # <_sre.SRE_Match object; span=(18, 19), match='I'> print(re.search(r"^d", string, flags=re.M)) print(re.search(r"e", string, flags=re.M))
运行结果:
None
<_sre.SRE_Match object; span=(21, 22), match='I'>
<_sre.SRE_Match object; span=(2, 3), match='d'>
<_sre.SRE_Match object; span=(18, 19), match='e'>