概述
正则表达式
正则表达式(英语:Regular Expression,常简写为regex、regexp或RE),又称正则表示式、正则表示法、规则表达式、常规表示法,是计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些匹配某个模式的文本。
许多程序设计语言都支持利用正则表达式进行字符串操作。例如,在Perl中就内建了一个功能强大的正则表达式引擎。正则表达式这个概念最初是由Unix中的工具软件(例如sed和grep)普及开的。
最初的正则表达式出现于理论计算机科学的自动控制理论和形式化语言理论中。在这些领域中有对计算(自动控制)的模型和对形式化语言描述与分类的研究。
1950年代,数学家斯蒂芬·科尔·克莱尼利用称之为“正则集合”的数学符号来描述此模型。肯·汤普逊将此符号系统引入编辑器QED,随后是Unix上的编辑器ed,并最终引入grep。自此以后,正则表达式被广泛地应用于各种Unix或类Unix系统的工具中。正则表达式的POSIX规范,分为基本型正则表达式(Basic Regular Expression,BRE)和扩展型正则表达式(Extended Regular Express,ERE)两大流派。在兼容POSIX的UNIX系统上,grep和egrep之类的工具都遵循POSIX规范,一些数据库系统中的正则表达式也匹配POSIX规范。grep、vi、sed都属于BRE,是历史最早的正则表达式,因此元字符必须转译之后才具有特殊含义。egrep、awk则属于ERE,元字符不用转译
Perl的正则表达式源自于Henry Spencer于1986年1月19日发布的regex,它已经演化成了PCRE(Perl兼容正则表达式,Perl Compatible Regular Expressions),一个由Philip Hazel开发的,为很多现代工具所使用的库。
各编程语言之间关于正则表达式的集成,目前开发进展得很差。Perl6的子项目Apocalypse的设计中已考虑到了这点。
理论
Python re 基本语法
Python re模块提供了与 Perl 语言类似的正则表达式匹配操作。Python re 官方文档
一个正则表达式通常被称为一个模式(pattern),为用来描述或者匹配一系列匹配某个句法规则的字符串。例如:Handel、Händel和Haendel这三个字符串,都可以由H(a|ä|ae)ndel这个模式来描述。大部分正则表达式的形式都有如下的结构:
选择
竖线|代表选择(即或集),具有最低优先级。例如gray|grey可以匹配grey或gray。
数量限定
某个字符后的数量限定符用来限定前面这个字符允许出现的个数。最常见的数量限定符包括+、?和*(不加数量限定则代表出现一次且仅出现一次):
加号+代表前面的字符必须至少出现一次。(1次或多次)。例如,goo+gle可以匹配google、gooogle、goooogle等;
问号?代表前面的字符最多只可以出现一次。(0次或1次)。例如,colou?r可以匹配color或者colour;
星号代表前面的字符可以不出现,也可以出现一次或者多次。(0次、1次或多次)。例如,042可以匹配42、042、0042、00042等。
匹配
圆括号()可以用来定义操作符的范围和优先度。例如,gr(a|e)y等价于gray|grey,(grand)?father匹配father和grandfather。
上述这些构造子都可以自由组合,因此H(ae?|ä)ndel和H(a|ae|ä)ndel是相同的,表示{“Handel”, “Haendel”, “Händel”}。
符号描述
模式 | 描述 |
---|---|
^ | 匹配字符串的开头 |
$ | 匹配字符串的末尾。 |
. | 匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符。 |
[…] | 用来表示一组字符,单独列出:[amk] 匹配 ‘a’,‘m’或’k’ |
[^…] | 不在[]中的字符:[^abc] 匹配除了a,b,c之外的字符。 |
re* | 匹配0个或多个的表达式。 |
re+ | 匹配1个或多个的表达式。 |
re? | 匹配0个或1个由前面的正则表达式定义的片段,非贪婪方式 |
re{ n} | 精确匹配 n 个前面表达式。例如, o{2} 不能匹配 “Bob” 中的 “o”,但是能匹配 “food” 中的两个 o。 |
re{ n,} | 匹配 n 个前面表达式。例如, o{2,} 不能匹配"Bob"中的"o",但能匹配 "foooood"中的所有 o。“o{1,}” 等价于 “o+”。“o{0,}” 则等价于 “o*”。 |
re{ n, m} | 匹配 n 到 m 次由前面的正则表达式定义的片段,贪婪方式 |
a | b 匹配a或b |
(re) | 对正则表达式分组并记住匹配的文本 |
(?imx) | 正则表达式包含三种可选标志:i, m, 或 x 。只影响括号中的区域。 |
(?-imx) | 正则表达式关闭 i, m, 或 x 可选标志。只影响括号中的区域。 |
(?: re) | 类似 (…), 但是不表示一个组 |
(?imx: re) | 在括号中使用i, m, 或 x 可选标志 |
(?-imx: re) | 在括号中不使用i, m, 或 x 可选标志 |
(?#…) | 注释. |
(?= re) | 前向肯定界定符。如果所含正则表达式,以 … 表示,在当前位置成功匹配时成功,否则失败。但一旦所含表达式已经尝试,匹配引擎根本没有提高;模式的剩余部分还要尝试界定符的右边。 |
(?! re) | 前向否定界定符。与肯定界定符相反;当所含表达式不能在字符串当前位置匹配时成功 |
(?> re) | 匹配的独立模式,省去回溯。 |
w | 匹配字母数字及下划线 |
W | 匹配非字母数字及下划线 |
s | 匹配任意空白字符,等价于 [ tnrf]。 |
S | 匹配任意非空字符 |
d | 匹配任意数字,等价于 [0-9]. |
D | 匹配任意非数字 |
A | 匹配字符串开始 |
Z | 匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串。 |
z | 匹配字符串结束 |
G | 匹配最后匹配完成的位置。 |
b | 匹配一个单词边界,也就是指单词和空格间的位置。例如, ‘erb’ 可以匹配"never" 中的 ‘er’,但不能匹配 “verb” 中的 ‘er’。 |
B | 匹配非单词边界。‘erB’ 能匹配 “verb” 中的 ‘er’,但不能匹配 “never” 中的 ‘er’。 |
n, t, 等. | 匹配一个换行符。匹配一个制表符。等 |
1…9 | 匹配第n个分组的内容。 |
10 | 匹配第n个分组的内容,如果它经匹配。否则指的是八进制字符码的表达式。 |
API 描述
re.compile
re.compile(pattern, flags=0)
将正则表达式的样式编译为一个 正则表达式对象 (正则对象),可以用于匹配,通过这个对象的方法 match(), search() 以及其他如下描述。
这个表达式的行为可以通过指定 标记 的值来改变。值可以是以下任意变量,可以通过位的OR操作来结合( | 操作符)。
序列
prog = re.compile(pattern)
result = prog.match(string)
等价于
result = re.match(pattern, string)
如果需要多次使用这个正则表达式的话,使用 re.compile() 和保存这个正则对象以便复用,可以让程序更加高效。
re.search
re.search(pattern, string, flags=0)
扫描整个 字符串 找到匹配样式的第一个位置,并返回一个相应的 匹配对象。如果没有匹配,就返回一个 None ; 注意这和找到一个零长度匹配是不同的。
re. match
re. match(pattern, string, flags=0)
如果 string 开始的0或者多个字符匹配到了正则表达式样式,就返回一个相应的 匹配对象 。 如果没有匹配,就返回 None ;注意它跟零长度匹配是不同的。
注意即便是 MULTILINE 多行模式, re.match() 也只匹配字符串的开始位置,而不匹配每行开始。
如果你想定位 string 的任何位置,使用 search() 来替代
re.fullmatch
re.fullmatch(pattern, string, flags=0)
如果整个 string 匹配到正则表达式样式,就返回一个相应的 匹配对象 。 否则就返回一个 None ;注意这跟零长度匹配是不同的。
re.split
3.4 新版功能.
re.split(pattern, string, maxsplit=0, flags=0)
用 pattern 分开 string 。 如果在 pattern 中捕获到括号,那么所有的组里的文字也会包含在列表里。如果 maxsplit 非零, 最多进行 maxsplit 次分隔, 剩下的字符全部返回到列表的最后一个元素。
>>>
>>> re.split(r'W+', 'Words, words, words.')
['Words', 'words', 'words', '']
>>> re.split(r'(W+)', 'Words, words, words.')
['Words', ', ', 'words', ', ', 'words', '.', '']
>>> re.split(r'W+', 'Words, words, words.', 1)
['Words', 'words, words.']
>>> re.split('[a-f]+', '0a3B9', flags=re.IGNORECASE)
['0', '3', '9']
如果分隔符里有捕获组合,并且匹配到字符串的开始,那么结果将会以一个空字符串开始。对于结尾也是一样
>>>
>>> re.split(r'(W+)', '...words, words...')
['', '...', 'words', ', ', 'words', '...', '']
这样的话,分隔组将会出现在结果列表中同样的位置。
样式的空匹配仅在与前一个空匹配不相邻时才会拆分字符串。
>>>
re.split(r'b', 'Words, words, words.')
['', 'Words', ', ', 'words', ', ', 'words', '.']
re.split(r'W*', '...words...')
['', '', 'w', 'o', 'r', 'd', 's', '', '']
re.split(r'(W*)', '...words...')
['', '...', '', '', 'w', '', 'o', '', 'r', '', 'd', '', 's', '...', '', '', '']
在 3.1 版更改: 增加了可选标记参数。
在 3.7 版更改: 增加了空字符串的样式分隔。
Flags 描述
re.A
re.ASCII
让 w, W, b, B, d, D, s 和 S 只匹配ASCII,而不是Unicode。这只对Unicode样式有效,会被byte样式忽略。相当于前面语法中的内联标志 (?a) 。
注意,为了保持向后兼容, re.U 标记依然存在(还有他的同义 re.UNICODE 和嵌入形式 (?u) ) , 但是这些在 Python 3 是冗余的,因为默认字符串已经是Unicode了(并且Unicode匹配不允许byte出现)。
re.I
re.IGNORECASE
进行忽略大小写匹配;表达式如 [A-Z] 也会匹配小写字符。Unicode匹配(比如 Ü 匹配 ü)同样有用,除非设置了 re.ASCII 标记来禁用非ASCII匹配。当前语言区域不会改变这个标记,除非设置了 re.LOCALE 标记。这个相当于内联标记 (?i) 。
注意,当设置了 IGNORECASE 标记,搜索Unicode样式 [a-z] 或 [A-Z] 的结合时,它将会匹配52个ASCII字符和4个额外的非ASCII字符: ‘İ’ (U+0130, 拉丁大写的 I 带个点在上面), ‘ı’ (U+0131, 拉丁小写没有点的 I ), ‘ſ’ (U+017F, 拉丁小写长 s) and ‘K’ (U+212A, 开尔文符号).如果使用 ASCII 标记,就只匹配 ‘a’ 到 ‘z’ 和 ‘A’ 到 ‘Z’ 。
re.L
re.LOCALE
由当前语言区域决定 w, W, b, B 和大小写敏感匹配。这个标记只能对byte样式有效。这个标记不推荐使用,因为语言区域机制很不可靠,它一次只能处理一个 "习惯”,而且只对8位字节有效。Unicode匹配在Python 3 里默认启用,并可以处理不同语言。 这个对应内联标记 (?L) 。
在 3.6 版更改: re.LOCALE 只能用于byte样式,而且不能和 re.ASCII 一起用。
在 3.7 版更改: 设置了 re.LOCALE 标记的编译正则对象不再在编译时依赖语言区域设置。语言区域设置只在匹配的时候影响其结果。
re.M
re.MULTILINE
设置以后,样式字符 ‘^’ 匹配字符串的开始,和每一行的开始(换行符后面紧跟的符号);样式字符 ‘
′
匹
配
字
符
串
尾
,
和
每
一
行
的
结
尾
(
换
行
符
前
面
那
个
符
号
)
。
默
认
情
况
下
,
’
’
匹
配
字
符
串
头
,
′
' 匹配字符串尾,和每一行的结尾(换行符前面那个符号)。默认情况下,’^’ 匹配字符串头,'
′匹配字符串尾,和每一行的结尾(换行符前面那个符号)。默认情况下,’’匹配字符串头,′’ 匹配字符串尾。对应内联标记 (?m) 。
最后
以上就是刻苦朋友为你收集整理的Python正则表达式 re的全部内容,希望文章能够帮你解决Python正则表达式 re所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复