Python基础六:Python 正则表达式

时间:2021-02-07 18:40:10

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'>