Python正则表达式之re

置顶 3周前 145次点击 来自 Python

Python正则表达式之re

re模块是python下用于正则表达式处理的模块,本文主要基于re --- 正则表达式操作文档,熟悉re模块的使用。

正则表达式

正则表达式,又称规则表达式。(英语:Regular Expression,在代码中常简写为regex、regexp或RE),计算机科学的一个概念。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。

字符组

在同一个位置可能出现的各种字符组成了一个字符组,在正则表达式中用[]表示:
| 正则表达式 | 待匹配字符 | 结果 | 说明 |
| ---- | ---- | ---- | ---- |
|[0-9] | -1 | False | [0-9]等同于[0123456789]|
|[^0-9] | a | False | 匹配非数字 |
|[0-9a-fA-F] |e |True |匹配数字,大小写形式的a~f,用来验证十六进制字符|

字符

元字符 匹配内容
. 匹配除换行符以外的任意字符
\w 匹配字母或数字或下划线
\s 匹配任意的空白符
\d 匹配数字
\n 匹配一个换行符
\t 匹配一个制表符
\b 匹配一个单词的结尾
^ 匹配字符串的开始
$ 匹配字符串的结尾
\W 匹配非字母或数字或下划线
\D 匹配非数字
\S 匹配非空白符
a b
() 匹配括号内的表达式,也表示一个组
[...] 匹配字符组中的字符
[^...] 匹配除了字符组中字符的所有字符

量词

量词 说明
* 重复零次或更多次
+ 重复一次或更多次
? 重复零次或一次
{n} 重复n次
{n,} 重复n次或更多次
{n,m} 重复n到m次

A|B

A 和 B 可以是任意正则表达式,创建一个正则表达式,匹配 A 或者 B. 任意个正则表达式可以用 '|' 连接。它也可以在组合(见下列)内使用。扫描目标字符串时, '|' 分隔开的正则样式从左到右进行匹配。当一个样式完全匹配时,这个分支就被接受。意思就是,一旦 A 匹配成功, B 就不再进行匹配,即便它能产生一个更好的匹配。或者说,'|' 操作符绝不贪婪。 如果要匹配 '|' 字符,使用 |, 或者把它包含在字符集里,比如 [|].

组合 ()

匹配括号内的任意正则表达式,并标识出组合的开始和结尾。匹配完成后,组合的内容可以被获取,并可以在之后用 \number 转义序列进行再次匹配。

我们以身份证来举例,先匹配[1-9]\d{16}[0-9x]如果没有匹配上就匹配[1-9]\d{14}

^([1-9]\d{16}[0-9x]|[1-9]\d{14})$

代码:

import re

print(re.findall('^([1-9]\d{16}[0-9x]|[1-9]\d{14})$', '110105199812067023'))

常用正则表达式实例

* ,+ , ? 等都是贪婪匹配,即尽可能匹配最长的字符串;后面加?号使其变成惰性匹配,即匹配最短字符串

正则表达式 待匹配字符 结果 说明
a. abacad ['ab', 'ac', 'ad'] 匹配以a开头的字符串
^a. abacad ab 只从开头匹配"a."
a.$ abacad ad 只匹配结尾的"a.$"
a.? abacad ['ab', 'ac', 'ad'] ?表示重复零次或一次,即只匹配"a"后面一个任意字符。
a.* abacad ['abacad'] * 表示重复零次或多次,即匹配"a"后面0或多个任意字符。
a.+ abacad ['abacad'] + 表示重复一次或多次,即只匹配"a"后面1个或多个任意字符。
a.{1,2} abacad ['aba', 'ad'] {1,2}匹配1到2次任意字符。
a.*? abacad ['a', 'a', 'a'] 惰性匹配
a.+? abacad ['ab', 'ac', 'ad'] 惰性匹配

代码:

import re

print(re.findall('a.', 'abacad'))
print(re.findall('^a.', 'abacad'))
print(re.findall('a.$', 'abacad'))
print(re.findall('a.?', 'abacad'))
print(re.findall('a.*', 'abacad'))
print(re.findall('a.+', 'abacad'))
print(re.findall('a.{1,2}', 'abacad'))
print(re.findall('a.*?', 'abacad'))
print(re.findall('a.+?', 'abacad'))

几个常用的非贪婪匹配Pattern:

*? 重复任意次,但尽可能少重复
+? 重复1次或更多次,但尽可能少重复
?? 重复0次或1次,但尽可能少重复
{n,m}? 重复n到m次,但尽可能少重复
{n,}? 重复n次以上,但尽可能少重复

re模块的使用

匹配模式

  • re.I 忽略大小写
  • re.L 表示特殊字符集 \w, \W, \b, \B, \s, \S 依赖于当前环境
  • re.M 多行模式
  • re.S 即为 . 并且包括换行符在内的任意字符(. 不包括换行符)
  • re.U 表示特殊字符集 \w, \W, \b, \B, \d, \D, \s, \S 依赖于 Unicode 字符属性数据库
  • re.X 为了增加可读性,忽略空格和 # 后面的注释

主要方法

  • re.compile: 编译一个正则表达式模式(pattern)
  • re.match: 从头开始匹配, 使用group()方法可以获取第一个匹配值
  • re.search: 用包含方式匹配,使用group()方法可以获取第一个匹配值
  • re.findall: 用包含方式匹配,把所有匹配到的字符放到以列表中的元素返回多个匹配值
  • re.sub: 匹配字符并替换
  • re.split: 以匹配到的字符当做列表分隔符,返回列表

re.compile

>>> import re
>>> email_pattern = re.compile(r'^[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+){0,4}
@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+){0,4}$')
>>> re.match(email_pattern, 'django@pyghon.org')
<_sre.SRE_Match object; span=(0, 17), match='django@pyghon.org'>

search() vs. match()

Python 提供了两种不同的操作:基于 re.match() 检查字符串开头,或者 re.search() 检查字符串的任意位置。
例如:

>>> re.match("c", "abcdef")    # No match
>>> re.search("c", "abcdef")   # Match
<re.Match object; span=(2, 3), match='c'>

在 search() 中,可以用 '^' 作为开始来限制匹配到字符串的首位

>>> re.match("c", "abcdef")    # No match
>>> re.search("^c", "abcdef")  # No match
>>> re.search("^a", "abcdef")  # Match
<re.Match object; span=(0, 1), match='a'>

注意 MULTILINE 多行模式中函数 match() 只匹配字符串的开始,但使用 search() 和以 '^' 开始的正则表达式会匹配每行的开始:

>>> re.match('X', 'A\nB\nX', re.MULTILINE)  # No match
>>> re.search('^X', 'A\nB\nX', re.MULTILINE)  # Match
<re.Match object; span=(4, 5), match='X'>

re.findall

>>> year_pattern = re.compile(r'\d{4}$') # 四位整数,匹配年份
>>> string1 = '我爱1998和1999年'
year_pattern.findall(string1)
['1998', '1999']

re.sub

>>> year_pattern = re.compile(r'\d{4}$') # 四位整数,匹配年份
>>> string1 = '我爱1998和1999年'
>>> replaced_str = re.sub(year_pattern, '****', string1)
>>> print(replaced_str)
我爱****和****年

re.split

>>> string1 = "1cat2dogs3cats4"
>>> import re
>>> list1 = re.split(r'\d+', string1)
>>> print(list1)
['', 'cat', 'dogs', 'cats', '']
Card image cap
开发者雷

尘世间一个小小的开发者,每天增加一些无聊的知识

要加油~~~

技术文档 >> 系列应用 >>
热推应用
Let'sLearnSwift
学习Swift的入门教程
PyPie
Python is as good as Pie
标签