python 正则表达式 断言_Python 之 RE(正则表达式)常用

正则表达式基础

提取字符串

语法

说明

可匹配字符串.

匹配除了换行符”\n”以外的任意字符

a.b

acb、adb、a2b、a~b

\

转义,将转义字符后面的一个字符改变成原来的意思

a[b\.\\]c

abc、a.c、a\c

[]

匹配括号内的任意字符

a[b,c,d,e]f

abd、acf、adf、aef

预定义字符

语法

说明

可匹配字符串^

以说明字符串开始

^123

123abc、123321、123zxc

$

以说明字符串结尾

123$

abc123、321123、zxc123

\b

匹配单词边界,不匹配任何字符

\basd\b

asd

\d

匹配数字 0~9

zx\dc

zx1c、zx2c、zx5c

\D

匹配非数字

zx\Dc

zxvc、zx$c、zx&c

\s

匹配空白符

zx\sc

zx c

\S

匹配非空白符

zx\Sc

zxac、zx1c、zxtc

\w

匹配字母、数字和下划线

zx\wc

zxdc、zx1c、zx_c

注意:

\b 匹配的只是一个位置,这个位置的一侧是构成单词的字符,另一侧为非单词字符、字符串的开始或结束位置。\b 是零宽度。

\w 在不同编码语言中匹配的范围是不一样的,在使用 ASCII 码的语言中匹配的是 [a-zA-Z0-9] ,而在使用 Unicode 码的语言中匹配的是 [a-zA-Z0-9] 和汉字、全角符号等特殊字符。

数量限定模式

语法

说明

可匹配字符串*

匹配 0 次到多次

zxc*

zx、zxccccc

+

匹配 1 次到多次

zxc+

zxc、zxccccc

?

匹配 0 次或 1 次

zxc?

zxc、zx

{m}

匹配 m 次

zxc{3}vb

zxcccvb

{m,}

匹配 m 次或多次

zxc{3,}vb

zxcccvb、zxccccccccvb

{,n}

匹配 0 次到 n 次

zxc{,3}vb

zxvb、zxcvb、zxccvb、zxcccvb

零宽断言

指的是当断言表达式为 True 时才进行匹配,但是并不匹配断言表达式内容。和 ^ 代表开头, $ 代表结尾, \b 代表单词边界一样,先行断言和后行断言也有类似的作用,它们只匹配某些位置,在匹配过程中,不占用字符,所以被称为零宽。所谓位置,是指字符串中第一个字符的左边、最后一个字符的右边以及相邻字符的中间。零宽断言表达式有四种:

零宽度负回顾后发断言 (?

贪婪 / 非贪婪 模式

正则表达式会尽可能多的去匹配字符,这被称为贪婪模式,贪婪模式是正则表达式默认的模式。但是有时候贪婪模式会给我们造成不必要的困扰,例如我们要匹配字符串 “Jack123Chen123Chen” 中的 “Jack123Chen”,但是贪婪模式匹配出的却是 “Jack123Chen123Chen”,这时我们就需要用到非贪婪模式来解决这个问题,非贪婪模式常用的表达式:

语法

说明*?

匹配 0 次或多次,但要尽可能少重复

+?

匹配 1 次或多次,但要尽可能少重复

??

匹配 0 次或 1 次,但要尽可能少重复

{m,}?

匹配 m 次或多次,但要尽可能少重复

OR 匹配又称匹配分支,也就是说只要有一个分支匹配就算匹配,这和我们在开发中使用的 OR 语句类似。OR 匹配利用 | 分割分支,例如我们需要匹配出英文姓名,但是在英文中姓和名中间有可能是以 · 分割,也有可能是以空格分隔,这时我们就可以利用 OR 匹配来处理这个问题。格式如下:[A-Za-z]+·[A-Za-z]+|[A-Za-z]+\s[A-Za-z]+

组合,将几个项组合为一个单元,这个单元可通过 * + ? | 等符号加以修饰,而且可以记住和这个组合相匹配的字符串以提供伺候的引用使用。分组使用 () 来表示。例如获取日期的正则表达式可以这么写:\d{4}-(0[1-9]|1[0-2])-(0[1-9]|12|3[01])。第一个分组 (0[1-9]|1[0-2]) 代表月的正则匹配,第二个分组 (0[1-9]|12|3[01]) 代表日的正则匹配。

Python 使用正则表达式

在 Python 中使用正则表达式很简单,re 模块提供了正则表达式的支持。使用步骤一共三步:

将正则表达式字符串转换为 Pattern 的实例;使用 Pattern 实例去处理要匹配的字符,匹配结果是一个 Match 实例;利用 Match 实例去进行之后的操作。

在 Python 中我们常用的 re 的方法有六种,分别是: compile、 match、 search、 findall、 split 和 sub。

compile

compile 方法的作用是将正则表达式字符串转化为 Pattern 实例,它具有两个参数 pattern 和 flags,pattern 参数类型是 string 类型,接收的是正则表达式字符串,flags 类型是 int 类型,接收的是匹配模式的编号,flags 参数是非必填项,默认值为 0 (忽略大小写)。flags 匹配模式有 6 种:

匹配模式

说明re.l

忽略大小写

re.M

多行匹配模式

re.S

任意匹配模式

re.L

预定义字符匹配模式

re.U

限定字符匹配模式

import re

pattern = re.compile(r'\d')

match

match 的作用是利用 Pattern 实例,从字符串左侧开始匹配,如果匹配到就返回一个 Match 实例,如果没有匹配到就返回 None。

import re

def getMatch(message):

pattern = re.compile(r'(\d{4}[-年])(\d{2}[-月])(\d{2}日{0,1})')

match = re.match(pattern, message)

if match:

print(match.groups())

for item in match.groups():

print(item)

else:

print("没匹配上")

if __name__ == '__main__':

message = "2019年01月23日大会开始"

getMatch(message)

message = "会议于2019-01-23召开"

getMatch(message)

以上代码使用了 groups 方法,这个方法用来获取匹配出来的字符串组。为什么第一段内容能匹配出来年月日,而第二段内容不能呢?这是因为 match 方法是从字符串的起始位置匹配的。代码运行结果:

(‘2019年’, ‘01月’, ‘23日’)

2019年

01月

23日

没匹配上

search

search 方法与 match 方法功能是一样的,只不过 search 方法是对整个字符串进行匹配。将前一小节代码中的 getMatch 方法进行改动,即可将第二段内容中的年月日匹配出来。

import re

def getMatch(message):

pattern = re.compile(r'(\d{4}[-年])(\d{2}[-月])(\d{2}日{0,1})')

match = re.search(pattern, message)

if match:

print(match.groups())

for item in match.groups():

print(item)

else:

print("没匹配上")

if __name__ == '__main__':

message = "2019年01月23日大会开始"

getMatch(message)

message = "会议于2019-01-23召开"

getMatch(message)

运行结果:

2019年

01月

23日

(‘2019-‘, ‘01-‘, ‘23’)

2019-

01-

23

findall

findall 方法的作用是匹配整个字符串,以列表的形式返回所有匹配结果。

import re

def getMatch(message):

pattern = re.compile(r'\w+')

match = re.findall(pattern, message)

if match:

print(match)

else:

print("没匹配上")

if __name__ == '__main__':

message = "my name is 张三"

getMatch(message)

message = "张三 is me"

getMatch(message)

运行结果:

[‘my’, ‘name’, ‘is’, ‘张三’]

[‘张三’, ‘is’, ‘me’]

split

split 方法是利用指定的字符来分割字符串。

import re

def getMatch(message):

pattern = re.compile(r'-')

match = re.split(pattern, message)

if match:

print(match)

else:

print("没匹配上")

if __name__ == '__main__':

message = "2018-9-12"

getMatch(message)

message = "第一步-第二步-第三步-第四步-and more"

getMatch(message)

运行结果:

[‘2018’, ‘9’, ‘12’]

[‘第一步’, ‘第二步’, ‘第三步’, ‘第四步’, ‘and more’]

sub

sub 方法用来替换字符串,它接受5个参数,其中常用的有三个:

pattern Pattern 实例

string 等待替换的字符串

repl 表示替换的新字符串或需要执行的替换方法

count 替换次数,默认为 0 表示全部替换

import re

def getMatch(match):

return match.group(0).replace(r'年龄', 'age')

if __name__ == '__main__':

message = "your 年龄 ?"

pattern=re.compile(r'\w+')

print(re.sub(pattern,getMatch,message))

运行结果:

your age ?

本作品采用《CC 协议》,转载必须注明作者和本文链接

不要试图用百米冲刺的方法完成马拉松比赛。

你可能感兴趣的:(python,正则表达式,断言)