python正则化表达式

Posted 非晚非晚

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python正则化表达式相关的知识,希望对你有一定的参考价值。

文章目录

re模块主要定义了 9个常量、12个函数、1个异常

1. 正则表达式的模式——pattern

模式字符串使用特殊的语法来表示一个正则表达式:

  1. 字母和数字表示他们自身。一个正则表达式模式中的字母和数字匹配同样的字符串
  2. 多数字母和数字前加一个反斜杠时会拥有不同的含义
  3. 标点符号只有被转义时才匹配自身,否则它们表示特殊的含义。
  4. 反斜杠本身需要使用反斜杠转义。
  5. 由于正则表达式通常都包含反斜杠,所以你最好使用原始字符串来表示它们。模式元素(如 r'\\t',等价于 '\\\\t')匹配相应的特殊字符

下表列出了正则表达式模式语法中的特殊元素。如果你使用模式的同时提供了可选的标志参数,某些模式元素的含义会改变。

模式描述
^匹配字符串的开头
$匹配字符串的末尾。
.匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符。
[…]用来表示一组字符,单独列出:[abc] 匹配’a’,‘b’或’c’
[^…]不在[]中的字符:[^abc] 匹配除了a,b,c之外的字符。
re*匹配0个或多个的表达式。
re+匹配1个或多个的表达式。
re?匹配0个或1个由前面的正则表达式定义的片段,非贪婪方式
re n精确匹配 n 个前面表达式。例如, o2 不能匹配 “Bob” 中的 “o”,但是能匹配 “food” 中的两个 o。
re n,匹配 n 个前面表达式。例如, o2, 不能匹配"Bob"中的"o",但能匹配 "foooood"中的所有 o。“o1,” 等价于 “o+”。“o0,” 则等价于 “o*”。
re n, m匹配 n 到 m 次由前面的正则表达式定义的片段,贪婪方式
(re)对正则表达式分组并记住匹配的文本
(?imx)正则表达式包含三种可选标志:i, m, 或 x 。只影响括号中的区域。
(?-imx)正则表达式关闭 i, m, 或 x 可选标志。只影响括号中的区域。
(?: re)类似 (…), 但是不表示一个组
(?imx: re)在括号中使用i, m, 或 x 可选标志
(?-imx: re)在括号中不使用i, m, 或 x 可选标志
(?#…)注释.
(?= re)前向肯定界定符。如果所含正则表达式,以 … 表示,在当前位置成功匹配时成功,否则失败。但一旦所含表达式已经尝试,匹配引擎根本没有提高;模式的剩余部分还要尝试界定符的右边。
(?! re)前向否定界定符。与肯定界定符相反;当所含表达式不能在字符串当前位置匹配时成功
(?> re)匹配的独立模式,省去回溯。
\\w匹配包括下划线的任何单词字符。等价于’[A-Za-z0-9_]'。
\\W匹配任何非单词字符。等价于 ‘[^A-Za-z0-9_]’。
\\s匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \\f\\n\\r\\t\\v]。。
\\S匹配任何非空白字符。等价于 [^ \\f\\n\\r\\t\\v]。
\\d匹配任意数字,等价于 [0-9].
\\D匹配一个非数字字符。等价于 [^0-9]。
\\A匹配字符串开始
\\Z匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串。
\\z匹配字符串结束
\\G匹配最后匹配完成的位置。
\\b匹配一个单词边界,也就是指单词和空格间的位置。例如, ‘er\\b’ 可以匹配"never" 中的 ‘er’,但不能匹配 “verb” 中的 ‘er’。
\\B匹配非单词边界。‘er\\B’ 能匹配 “verb” 中的 ‘er’,但不能匹配 “never” 中的 ‘er’。
\\n, \\t, 等.匹配一个换行符。匹配一个制表符。等
\\1…\\9匹配第n个分组的内容。
\\10匹配第n个分组的内容,如果它经匹配。否则指的是八进制字符码的表达式。

2. 正则表达式常量——修饰符

(1)常量理解

常量即表示不可更改的变量,一般用于做标记。re模块中有9个常量,常量的值都是int类型,并且所有的常量都是在RegexFlag枚举类来实现

需要说明的是,这9个常量值是可以叠加使用的,叠加时请使用 | 符号。

修饰符简写描述
re.IGNORECASEre.I进行忽略大小写匹配
re.ASCIIre.AASCII表示ASCII码的意思,让 \\w, \\W, \\b, \\B, \\d, \\D, \\s 和 \\S 只匹配ASCII,而不是Unicode。
re.DOTALLre.SDOT表示.,ALL表示所有,连起来就是.匹配所有,包括换行符\\n。默认模式下.是不能匹配行符\\n的。
re.MULTILINEre.M多行模式,当某字符串中有换行符\\n,默认模式下是不支持换行符特性的,比如:行开头 和 行结尾,而多行模式下是支持匹配行开头的。
re.VERBOSEre.X详细模式,可以在正则表达式中加注解。
re.LOCALEre.L由当前语言区域决定 \\w, \\W, \\b, \\B 和大小写敏感匹配,这个标记只能对byte样式有效。这个标记官方已经不推荐使用,因为语言区域机制很不可靠,它一次只能处理一个 "习惯”,而且只对8位字节有效。
re.UNICODEre.U与 ASCII 模式类似,匹配unicode编码支持的字符,但是 Python3 默认字符串已经是Unicode,所以有点冗余。
re.DEBUG显示编译时的debug信息。
re.TEMPLATEre.T

9个常量在re常用函数中都可以使用。前5个(IGNORECASE、ASCII、DOTALL、MULTILINE、VERBOSE)较为实用,两个(LOCALE、UNICODE)官方不建议使用、两个(TEMPLATE、DEBUG)试验性功能,不能依赖。

下面使用代码来更直观地查看常用正则表达式常量的使用。

(2)re.IGNORECASE

import re

text = 'QLEE'
pattern = 'qlee'

print('默认模式:', re.findall(pattern, text))
print('忽略大小写模式:', re.findall(pattern, text, re.IGNORECASE))

输出:

默认模式: []
忽略大小写模式: ['QLEE']

(3)re.ASCII

import re

text = '我是QLEE大家hao'
pattern = r'\\w+'

print('unicode:', re.findall(pattern, text))
print('ASCII:', re.findall(pattern, text, re.ASCII))) #只匹配ASCII编码支持的字符

输出:

unicode['我是QLEE大家hao']
ASCII: ['QLEE', 'hao']

(4)re.DOTALL

import re

text = '我是QLEE\\n大家hao'
pattern = r'.*'

print('默认模式:', re.findall(pattern, text)) #默认模式可以去掉换行符
print('匹配所有模式:', re.findall(pattern, text, re.DOTALL)) #换行符也匹配

输出:

默认模式: ['我是QLEE', '', '大家hao', '']
匹配所有模式: ['我是QLEE\\n大家hao', '']

3. 正则表达式函数


需要说明的是:查找一个匹配项(search、match、fullmatch)的函数返回值都是一个 匹配对象Match ,需要通过match.group() 获取匹配值

group() 返回被 RE 匹配的字符串。

类型说明
group(num=0)匹配的整个表达式的字符串,当要获得整个匹配的子串时,可直接使用 group() 或 group(0),第一个为group(1),其他依次类推
groups()返回一个包含所有小组字符串的元组,从 1 到 所含的小组号。
  • start(): 返回匹配开始的位置
  • end(): 返回匹配结束的位置
  • span(): 返回一个元组包含匹配 (开始,结束) 的位置
  • 举例说明
import re

pattern = r'([a-z]+) ([a-z]+)' 
text = 'Hello World Wide Web'        # 查待匹配的字符串

tmp = re.match(pattern, text, re.I)

print('match : ', tmp)
print('group : ', tmp.group()) #所有匹配的字符串
print('group(1) : ', tmp.group(1)) #第一个匹配的字符串
print('start : ', tmp.start()) #所有的开始
print('end : ', tmp.end())# 所有的结束
print('span : ', tmp.span(2)) #第2个的开始与结束

输出:

match :  <_sre.SRE_Match object; span=(0, 11), match='Hello World'>
group :  Hello World
group(1) :  Hello
start :  0
end :  11
span :  (6, 11)

(1)查找一个匹配项——match、search和fullmatch

  • re.match: 必须从字符串开头匹配
  • re.search: 查找任意位置的匹配项
  • re.fullmatch: 整个字符串与正则完全匹配
import re

text = 'aqleebqlee,cqlee'
pattern = 'qlee'

# match,只匹配开头
print('match:', re.match(pattern, text))
# search,匹配任意位置
print('search:', re.search(pattern, text))
# fullmatch,全部匹配
print('fullmatch', re.fullmatch(pattern, text))


print('group获取匹配的值:', re.search(pattern, text).group())

输出:

matchNone
search: <_sre.SRE_Match object; span=(1, 5), match='qlee'>
fullmatch None
group获取匹配的值: qlee

search函数是在字符串中任意位置匹配,只要有符合正则表达式的字符串就匹配成功,其实有两个匹配项,但search函数值返回一个。

而match函数是要从头开始匹配,而字符串开头多了个字母a,所以无法匹配,fullmatch函数需要完全相同,故也不匹配!

(2)查找多个匹配项——findall、finditer

  • re.findall: 从字符串任意位置查找,返回一个列表
  • re.finditer:从字符串任意位置查找,返回一个迭代器

两个方法基本类似,只不过一个是返回列表,一个是返回迭代器。我们知道列表是一次性生成在内存中,而迭代器是需要使用时一点一点生成出来的,内存使用更优。

import re

text = 'aqleebqlee,cqlee'
pattern = 'qlee'

# findall,返回所有匹配值,组成列表形式
print('findall: ', re.findall(pattern, text))

# finditer,返回匹配的迭代器,需要转化为list
print('finditer: ', list(re.finditer(pattern, text)))

输出:

findall:  ['qlee', 'qlee', 'qlee']
finditer:  [<_sre.SRE_Match object; span=(1, 5), match='qlee'>, <_sre.SRE_Match object; span=(6, 10), match='qlee'>, <_sre.SRE_Match object; span=(12, 16), match='qlee'>]

(3)分割——split

  • 函数形式
re.split(pattern, string, maxsplit=0, flags=0) 
  • pattern:分开 string
  • maxsplit: 表示最多进行分割次数
  • flags:表示模式
import re

text = 'aqleebqlee,cqlee'
pattern = 'qlee'

print('split: ', re.split(pattern, text, maxsplit=1, flags=re.IGNORECASE))

输出:

split:  ['a', 'bqlee,cqlee']

(4)替换——sub、subn

re.subn与sub函数功能一致,只不过subn返回一个元组(字符串, 替换次数)

re.sub(pattern, repl, string, count=0, flags=0) 
  • repl替换掉string中被pattern匹配的字符
  • count表示最大替换次数
  • flags表示正则表达式的常量
import re

text = 'aqleebqlee,cqlee'
pattern = ','
repl = '/'

# 将','换成'/'
print('sub: ', re.sub(pattern, repl, text, count=2, flags=re.IGNORECASE))

输出:

sub:  aqleebqlee/cqlee

(5)编译正则项——template、compile

compile函数 与 template函数功能为将正则表达式的样式编译为一个正则表达式对象 (正则对象Pattern),这个对象与re模块有同样的正则函数。

这一块暂时用得较少,暂时不做讲解。

(6)其他——escape、purge

  • escape

re.escape(pattern) 可以转义正则表达式中具有特殊含义的字符。

pattern = r'qlee\\.qlee\\*'

等价于:

pattern = re.escape(qlee.qlee*)

re.escape(pattern) 看似非常好用省去了我们自己加转义,但是使用它很容易出现转义错误的问题,所以并不建议使用它转义,而建议大家自己手动转义

  • purge

re.purge() 函数作用就是清除正则表达式缓存

4. 一些简短示例

(1)常用匹配模式

例子描述
[Pp]ython匹配 “Python” 或 “python”
[aeiou]匹配中括号内的任意一个字母
[^aeiou]除了aeiou字母以外的所有字符
[0-9]匹配任何数字。类似于 [0123456789]
[a-z]匹配任何小写字母
[A-Z]匹配任何大写字母
[a-zA-Z0-9]匹配任何字母及数字
[^0-9]匹配除了数字外的字符

(2)多个匹配模式——提取字符串和字符

import re

# 提取字符和数字
'''
\\w: 匹配包括下划线的任何单词字符
\\d: 匹配数字
+: 匹配一个或多个,要不然只会匹配一个字符和一个数字
'''
result = re.findall(r'(\\w+)=(\\d+)', 'set width=20 and height=10')
print(result)

输出:

[('width', '20'), ('height', '10')]

以上是关于python正则化表达式的主要内容,如果未能解决你的问题,请参考以下文章

python正则化表达式

python - urls.py正则表达式帮助坐标

python正则表达式

寻求使用python在一个大文件中进行正则表达式

js 正则表达式之环视结构

1.1正则表达式