Python3 中使用正则表达式

译者:anxin
日期:2017-12-17

Python3 提供re模块来操作正则表达式,re模块中提供了相应的函数在Python3中使用正则表达式。

Python3 正则表达式反斜杠带来的麻烦

正则表达式是嵌入到Python3中的一种编程语言,在正则表达式中使用反斜杠 "\" 转义特殊字符,然而在Python3语言中也使用反斜杠 "\" 转义特殊字符,这就造成了一定的冲突。

设想:你想要使用正则表达式匹配字符串“\section”,因为反斜杠 \ 在正则表达式中是特殊字符,所以必须进行转义,那么正则表达式的模式字符串就需要写为“\\section”。正则表达式语言需要嵌入到Python3语言中使用,Python3同样使用反斜杠 "\" 转义特殊字符,所以要使用Python3输入字符串“\\section”,需要对其中的两个反斜杠转义,那么在Python3语言中使用的字符串就需要写为“\\\\section”。

以下几个要点帮助你理解“\\\\section”字符串:

  1. 正则表达式的模式字符串首先看做Python3的字符串,由Python3处理后作为正则表达式微语言的输入字符串。
  2. Python3语言使用反斜杠 "\" 转义反斜杠,每个反斜杠转义其后的反斜杠,所以经Python3语言处理后的输出的字符串为“\\section”。
  3. 正则表达式微语言使用反斜杠 "\" 转义反斜杠,所以经正则表达式语言处理后的输出字符串为“\section”,得到需要表示的字符串。

这种形式的字符串就不利于用户读懂,所以在Python3中使用原生字符串(raw string)表示正则表达式的模式字符串,如下所示:

>>> p = re.compile(r"\\section")

如果你需要进一步了解原生字符串(raw string),查看:Python3 字符串类型

Python3 使用正则表达式匹配字符串

Python3 的re模块提供了compile(pattern)函数编译正则表达式生成正则表达式模式对象,然后使用模式对象匹配字符串。这种方式的好处是,正则表达式模式对象可以重复使用,需要重复使用一个模式时使用此方式。

1)Python3 使用正则表达式匹配字符串之前,首先要使用要使用re模块提供的compile()函数把Python3的正则表达式模式编译生成一个Python3的正则表达式模式对象。

>>> import re
>>> p = re.compile('[a-z]+')
>>> p
re.compile('[a-z]+')

2)使用Python3编译生成的模式对象的match()函数匹配字符串,它返回一个正则表达式的匹配对象(Match Object):

match()函数从字符串的第一个字符匹配模式,如果第一个字符与模式不匹配,则匹配失败。

m = p.match('tempo')
>>> m
<_sre.SRE_Match object; span=(0, 5), match='tempo'>

3)使用Python3编译生成的模式对象的search()函数匹配字符串,它返回一个正则表达式的匹配对象(Match Object):

search()函数不像match()函数那样,search()函数查找字符串中是否存在与模式匹配的子串,如果存在则返回一个匹配对象,否则匹配失败。

>>> print(p.match('::: message'))
None
>>> m = p.search('::: message')
>>> m
<_sre.SRE_Match object; span=(4, 11), match='message'>
>>> m.group()
'message'
>>> m.span()
(4, 11)

注:如上match()函数没有与模式匹配的字符串,而search()函数有与模式匹配的字符串。

4)使用Python3编译生成的模式对象的findall()函数返回与模式匹配的一个字符串列表:

>>> p = re.compile('\d+')
>>> p.findall('12 drummers drumming, 11 pipers piping, 10 lords a-leaping')
['12', '11', '10']

Python3 re模块级正则表达式函数

在Python3 的re模块中也提供了和模式对象相对应的match(pattern, string),search(pattern, string),findall(pattern, string)等方法,这些方法的第一个参数pattern为模式字符串,第二个参数string为需要匹配的字符串,如下所示:

>>> m = re.match(r"(\w+) (\w+)", "Isaac Newton, physicist")
>>> m
<_sre.SRE_Match object; span=(0, 12), match='Isaac Newton'>

Python3 获取匹配的字符串

Python3 使用正则表达式模式匹配字符串后,返回一个匹配对象(Match Object),Match Object具有如下常用的函数:

方法 说明
group() 无参数,返回完全匹配的字符串(即:0 位置的字符串),带参数,返回特定位置的分组(参数为整数)分组的概念将在Python3正则表达式的分组介绍
start() 返回匹配字符串在原字符串中的起始位置
end() 返回匹配字符串在原字符串中的结束位置
span() 返回匹配字符串在原字符串中的起始位置和结束位置的一个元组

Match Object方法的使用实例如下:

>>> m = re.match(r"(\w+) (\w+)", "Isaac Newton, physicist")
>>> m.group()
'Isaac Newton'
>>> m.span()
(0, 12)
>>> m.start()
0
>>> m.end()
12
>>> m.group(0)
'Isaac Newton'
>>> m.group(1)
'Isaac'
>>> m.group(2)
'Newton'

Python3 正则表达式编译标志

正则表达式中可以使用编译标志来修改正则表达式默认的匹配行为,标志就有两种形式的名字,一种是全名,另一种是单字符名,如:匹配时忽略大小写标志的全名为IGNORECASE,单字符名为I

1)使用re.IGNORECASE标志,在正则表达式匹配时,忽略大小写:

>>> p = re.compile(r"python3", re.IGNORECASE)
>>> m = p.match("Python3")
>>> m
<_sre.SRE_Match object; span=(0, 7), match='Python3'>
>>> m.group()
'Python3'

2)re.VERBOSE标记允许在正则表达式中使用注释,注释以 # 开头,使用re.VERBOSE标记的正则表达式如下所示:

charref = re.compile(r"""
 &[#]                # Start of a numeric entity reference
 (
     0[0-7]+         # Octal form
   | [0-9]+          # Decimal form
   | x[0-9a-fA-F]+   # Hexadecimal form
 )
 ;                   # Trailing semicolon
""", re.VERBOSE)

它等同于如下不使用re.VERBOSE标记的正则表达式:

charref = re.compile("&#(0[0-7]+"
                     "|[0-9]+"
                     "|x[0-9a-fA-F]+);")

Python3 正则表达式中可用的编译标志如下所示:

标志 说明
ASCII, A 使\w, \b,\s \d 只匹配各自对应的ASCII字符
DOTALL, S 使 . 匹配任意的字符,包括换行符
IGNORECASE, I 匹配时忽略大小写
LOCALE, L 使\w, \b,\s \d 匹配各自对应的本地编码中字符,而不是匹配Unicode编码,并且匹配时忽略大小写
MULTILINE, M 匹配多行,影响 ^$ 的匹配,具体查看Python3 正则表达式基本语法
VERBOSE, X (代表 ‘extended’) 在正则表达式中可以使用注释,易于阅读

Python3 使用正则表达式修改字符串

以上介绍了使用Python3的正则表达式查找字符串,正则表达式也可以用来修改字符串,常用的有以下方法:

方法 作用
split() 把字符串分割为一个列表,当RE匹配时对字符串进行分割
sub() 查找所有与模式匹配的子串,并使用一个不同的字符串替换
subn() 和sub()的作用相同,但是返回的是由新字符串和替换的子串数组成的元组

分割字符串

Python3正则表达式模式对象具有split()方法,用于分割字符串,当然Python3中具有对应的re模块级函数re.split()用于分割字符串,它们的作用相同。

.split(string[, maxsplit=0])

参数解释:

  • string:需要分割的字符串
  • maxsplit:如果不为0,把字符串分割成的最大子串数,如为0,则不受限制。

使用模式对象的split()方法分割字符串的实例如下(你也可以使用模块级函数):

>>> p = re.compile(r'\W+')
>>> p.split('This is a test, short and sweet, of split().')
['This', 'is', 'a', 'test', 'short', 'and', 'sweet', 'of', 'split', '']
>>> p.split('This is a test, short and sweet, of split().', 3)
['This', 'is', 'a', 'test, short and sweet, of split().']

替换字符串

Python3正则表达式模式对象具有sub()方法,用于替换字符串,当然Python3中具有对应的re模块级函数re.sub()用于替换字符串,它们的作用相同。

 .sub(replacement, string[, count=0])

参数解释:

  • replacement:用于替换的字符串
  • string:需要分割的字符串
  • count:如果不为0,替换字符串的最大次数,如为0,则不受限制。

使用模式对象的sub()方法替换字符串的实例如下(你也可以使用模块级函数):

>>> p = re.compile('(blue|white|red)')
>>> p.sub('colour', 'blue socks and red shoes')
'colour socks and colour shoes'
>>> p.sub('colour', 'blue socks and red shoes', count=1)
'colour socks and red shoes'
本文链接:/tutorial/python3/python3-shiyong-zhengze-biaodashi

本文版权归知站所有,未经站长同意不得转载,谢谢尊重作者劳动成果!