Python 正则表达式(Regex)

来源:互联网 发布:python 字典是什么 编辑:程序博客网 时间:2024/04/29 20:59

这里写图片描述
这里写图片描述
(1)* :是指字符匹配0次或者无限次,也就是说当某个字符出现一次或者无限次是 ==+,只有当 前面的字符可以不出现时,*!=+;加号(+)前面的字符最少出现一次
(2) 对于贪婪模式和非贪婪模式:? +? ?? 表示的意思是尽可能的少匹配或者不匹配前一个字符,具体可以匹配的次数还是与原来+?的定义一致。比如:ma =re.match(r’[0-9][a-z]*?’)就是尽量不去匹配最后一个[a-z]字符

这里写图片描述

正则表达式使用反斜杠" \ "来代表特殊形式或用作转义字符,这里跟Python的语法冲突,因此,Python用" \\\\ "表示正则表达式中的" \ ",因为正则表达式中如果要匹配" \ ",需要用\来转义,变成" \\ ",而Python语法中又需要对字符串中每一个\进行转义,所以就变成了" \\\\ "。上面的写法是不是觉得很麻烦,为了使正则表达式具有更好的可读性,Python特别设计了原始字符串(raw string),需要提醒你的是,在写文件路径的时候就不要使用raw string了,这里存在陷阱。raw string就是用'r'作为字符串的前缀,如 r"\n":表示两个字符"\"和"n",而不是换行符了。Python中写正则表达式时推荐使用这种形式。绝大多数正则表达式操作与 模块级函数或RegexObject方法 一样都能达到同样的目的。而且不需要你一开始就编译正则表达式对象,但是不能使用一些实用的微调参数。

martch和search的区别

Python提供了两种不同的原始操作:match和search。match是从字符串的起点开始做匹配,而search(perl默认)是从字符串做任意匹配。

编译标志

编译标志让你可以修改正则表达式的一些运行方式。在 re 模块中标志可以使用两个名字,一个是全名如 IGNORECASE,一个是缩写,一字母形式如 I。(如果你熟悉 Perl 的模式修改,一字母形式使用同样的字母;例如 re.VERBOSE的缩写形式是 re.X。)多个标志可以通过按位 OR-ing 它们来指定。如 re.I | re.M 被设置成 I 和 M 标志:

I
IGNORECASE

使匹配对大小写不敏感;字符类和字符串匹配字母时忽略大小写。举个例子,[A-Z]也可以匹配小写字母,Spam 可以匹配 "Spam", "spam", 或 "spAM"。这个小写字母并不考虑当前位置。

L
LOCALE

影响 "w, "W, "b, 和 "B,这取决于当前的本地化设置。locales 是 C 语言库中的一项功能,是用来为需要考虑不同语言的编程提供帮助的。举个例子,如果你正在处理法文文本,你想用 "w+ 来匹配文字,但 "w 只匹配字符类 [A-Za-z];它并不能匹配 "é" 或 "?"。如果你的系统配置适当且本地化设置为法语,那么内部的 C 函数将告诉程序 "é" 也应该被认为是一个字母。当在编译正则表达式时使用 LOCALE 标志会得到用这些 C 函数来处理 "w 後的编译对象;这会更慢,但也会象你希望的那样可以用 "w+ 来匹配法文文本。

M
MULTILINE

(此时 ^ 和 $ 不会被解释; 它们将在 4.1 节被介绍.)使用 "^" 只匹配字符串的开始,而 $ 则只匹配字符串的结尾和直接在换行前(如果有的话)的字符串结尾。当本标志指定後, "^" 匹配字符串的开始和字符串中每行的开始。同样的, $ 元字符匹配字符串结尾和字符串中每行的结尾(直接在每个换行之前)。

S
DOTALL

使 "." 特殊字符完全匹配任何字符,包括换行;没有这个标志, "." 匹配除了换行外的任何字符。

X
VERBOSE

该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。当该标志被指定时,在 RE 字符串中的空白符被忽略,除非该空白符在字符类中或在反斜杠之後;这可以让你更清晰地组织和缩进 RE。它也可以允许你将注释写入 RE,这些注释会被引擎忽略;注释用 "#"号 来标识,不过该符号不能在字符串或反斜杠之後。

最后:如果能用字符串的方法,就不要选择正则表达式,因为字符串方法更简单快速。

————————-追加更新———————–

包括以下元字符:
.
(Dot)在默认模式下,它匹配除了换行符号以外的任意字符。如果指定了DOTALL,那它将可匹配换行符。

^
(Caret)匹配字符串的开始,即物理行的开始,在多行模式下,也可匹配换行符后的位置,即逻辑行的开始。

$
匹配字符串的结尾或在字符串尾部的换行符之前的位置,在多行模式下,还可以匹配到一个新的行之前的位置。foo可以匹配’foo’和’foobar’,而foo$只匹配’foo’。更有趣的是,在’foo1\nfoo2\n’中搜索foo.$,默认模式下匹配到’foo2’,而在多行模式下,可匹配到’foo1’和’foo2’。不指定多行模式,$匹配物理行的结尾,而foo1为串的逻辑行之前的字符,所以未被匹配。

*
描述前边邻近的字符或子表达式,匹配0个或多个重复,因为许多重复是有可能的。ab*将匹配’a’,’ab’,或者’a’后面跟大量的’b’。

+
描述前边邻近的字符或子表达式,匹配1个或多个重复。ab+将匹配’a’和后面跟着不少于1个的b,但不单独匹配’a’。

?
描述前边邻近的字符或子表达式,匹配0个或1个重复。ab?将匹配’a’或’ab’。

*?、+?、??
使用”“、”+”、”?”这些量词描述符都是贪婪匹配的,它们会匹配尽可能多的字符。有时,这种行为并非是我们想要的,若使用<.>去匹配’”<\H1>title”’,它将会匹配整个字符串,而不只是’‘。在量词描述符后面添加”?”后,会使匹配过程里,变为非贪婪模式,匹配尽可能少的字符。使用<.*?>去匹配之前的字符串,将只匹配<\H1>。

{m}
描述前边邻近的字符或子表达式,尝试匹配尽可能多的m个重复。例如,a{6}匹配6个’a’,不是5个。

{m,n}
描述前边邻近的字符或子表达式,尝试匹配尽可能多从m个到n个重复。例如a{3,5}将匹配3至5个’a’,省略m,默认为0,即是匹配下限为0个,省略n则是匹配上限为无限。例如,a{4,}将匹配’aaaab’里的4个a或其中包含成千上万个’a’,但最少应该有4个’a’,并不匹配’aaab’,逗号不可省略,以免与之前介绍的描述符冲突。

{m,n}?
描述前边邻近的字符或子表达式,尝试匹配尽可能少从m个到n个重复。这是非贪婪版本的{m,n}。例如,在6个字符的字符串’aaaaaa’,a{3,5}将匹配5个’a’,而a{3,5}?将匹配3个’a’。

\
用于转义元字符,或者简写标记的声明(将在下边谈论)。如果在python里你不适用raw原始字符串来作为表达式,请记住,表达式还需要为每个反斜杆前边在用一个反斜杆来转义。若转义序列并非由python作解析,那么\将会直接修饰之后的字符。但是如果由python来解释表达式,反斜杆应该重复2次。这比较复杂,不容易理解,所以强烈建议使用最简单的raw格式的原始字符串来写表达式。例如,r”aaa(a)”匹配’aaa(a)’,假如使用普通字符串来编写表达式:”aaa\(a\)”。

[]
用于描述一个字符组(台翻译为字符集)。字符组可以是由多个单独字符组成,也可以使用连字符-来表示字符范围。特殊字符在字符组里是无效的,只作为普通字符描述。例如,[akm]akm’里的其中一个字符;[a-z]将匹配所有小写字母,[a-zA-Z0-9]将匹配所有字母和数字;简写标记也可以在字符组里描述。如果你想包含’]’或者’-‘,那就在该字符前使用反斜杆转义,或者将它写在字符组的第一个,例如[]]匹配’]’,注意,假如同时需要匹配’-‘和’]’,就只能把其中一个放在第一位,另一个用反斜杆转义,推荐对所有不需要的元字符都使用反斜杆转义。您还可以匹配一个除了字符组里描述字符以外的字符,以脱字符’^’作为第一个字符,将标示这是一个排除型字符组,^在别的位置,只会匹配普通的’^’字符。例如,[^5]匹配除了5以外的字符;[^^]匹配除了脱字符以外的字符。

|
A|B,其中A和B可以是任意的子表达式,该表达式将可匹配A或者B。表达式里可以使用任意数量的|进行多选分支的分隔。这可用于分组捕获等(见下文)。对目标字符串进行扫描时,|是从左到右的顺序进行分隔。当一个分支被完全匹配,那么该分支就会被接受,这以为着,一旦A匹配,B就永远不会被尝试匹配。即使B会匹配更长的字符串。换句话说,在|操作符里,是永远不会贪婪匹配的。要匹配一个普通字符|,可使用|转义写法,或者用字符组包含:[|]。

(…)
正则表达式会匹配括号内的字符,从开始字符到结束字符分为一个组,该组在捕获完成之后,可使用\数字来进行反向引用。需要匹配字符’(‘、’)’时,使用转义符进行转义’(‘、’)’,或者用字符组:[(]、[)]。

(?…)
捕获组中可使用扩展功能符,在(之后使用?,在?之后描述进一步的语法含义。扩展通常不会进行新的捕获,(?P)除外。
以下是目前支持的扩展功能:

(?iLmsux)
(可以一个或者多个修饰符同时使用:’i’,’L’,’m’,’s’,’u’,’x’)
该组匹配空字符串;在模块中,相应的设置标志:re.I,re.L,re.M,re.S,re.U,re.X。如果你需要在表达式中指定匹配标志,而不是通过编译函数来指定,这是非常有用的,编译标志将影响整个表达式。请注意,(?x)的标志改变表达式的书写规则,如果在该标志之后包含了空白字符,那空白字符将会被忽略。例如aa(?i)a可匹配’AaA’。

(?:)
捕获组的无捕获版本。正则表达式会捕获任何在括号内的内容,但该捕获组不会捕获任何内容,也不可用于反向引用。一般用于做子表达式的界定符,例如给aa|b加限定:a(?:a|b)匹配’a’之后还有’a’或者’b’,而不是原本的匹配’aa’或者匹配b。

(?P…)
功能类似捕获组,但该组匹配后可通过一个名称来引用捕获内容。分组名必须是有效的python标识符,每个组名在一个表达式只能被用一次。一个没有声明组名的捕获组其实也是一个id编号组。所以在上面的例子里,也可以把组命名并且进行反向引用。例如,表达式是:(?P[a-zA-Z_]\w*),该匹配结果的对象可通过指定组名来返回,m.group(‘id’)或者m.end(‘id’),并且在表达式中可用(?P=id)来进行反向引用,或者用\g进行替换文本。
示例:

m = re.match(‘a(?Pb)cde’,’abcde’) #命名捕获组id捕获b
m.group() #获取所有成功匹配内容
‘abcde’
m.group(‘id’) #获取id组捕获内容
‘b’
m.end(‘id’) #获取id组成功匹配结束位置点
2
m.end() #获取整个表达式成功匹配结束位置点
5
m = re.match(‘a(?Pb)cde(?P=id)’,’abcdeb’) #反向引用了id组
m.group()
‘abcdeb’
re.sub(‘a(?Pb)cde(?P=id)’,’ab\gh’,’abcdeb’) 在替换中指定替换为id组的内容(b)
‘abbh’

(?P=name)
反向引用,匹配之前对应的命名组所捕获的内容。

(?#…)
注释,包含在该括号内的内容将被忽略。

(?=…)
如果当前位置可匹配…,那么匹配接下来的表达式,但这个匹配只是一个判断,它并不消耗、占有任何字符,这被称为后向断言(顺序肯定环视)。例如Isaac (?=Asimov)可以匹配Isaac,但它后边必须跟着’Asimov’。

(?!…)
如果当前位置不可匹配…,那么匹配接下来的表达式。这是后向否定断言(顺序否定环视),例如,Isaac (?!Asimov) 会匹配 ‘Isaac ’ ,当它后边不是跟着 ‘Asimov’的时候。

(?<=…)
如果当前位置点的前面符合某些条件,那么从这个点开始匹配接下来的表达式。这被称为前向断言(逆序肯定环视)。(?<=abc)会找到一个匹配在字符串’abcdef’中,在匹配位置点向前检查三个字符,符合包含在断言里的描述的三个字符。断言所包含的表达式必须是固定长度的(不能使用量词修饰),这意味着a|b是被允许的,而a*、a{3,4}是不允许的。请注意,使用后向断言永远不会从字符串开始进行匹配,你需要使用的函数可能是search(),而不是match(),因为match()是从字符串开头进行匹配,否则失败,而使用环视功能会导致该函数失败:

import re
m = re.search(‘(?<=abc)def’, ‘abcdef’)
m.group(0)
‘def’

This example looks for a word following a hyphen:

m = re.search(‘(?<=-)\w+’, ‘spam-egg’)
m.group(0)
‘egg’

(?<!…)
如果当前位置点的前面不符合某些条件,那么从这个点开始匹配接下来的表达式。这就是所谓的前向否定断言(逆序否定环视)。类似后向否定断言,所包含的表达式必须是固定长度的字符串。在前向否定断言里的表达式可能会在字符串开始被搜索。

(?(id/name)yes-pattern|no-pattern)
如果存在并捕获成功指定编号或命名的捕获组,就会尝试匹配yes-pattern,如果捕获失败,那么尝试匹配no-pattern,|no-pattern是可省略的。例如,(<)?(\w+@\w+(?:.\w+)+)(?(1)>)是一个匹配电子邮件地址的表达式,将匹配’user@host.com’ 或者 ‘user@host.com’这样的格式,但不匹配’user@host.com'。该功能在2.4版本新加入。

元字符序列由’\’和下面列出的普通字符组成。如果字符不在下列,那么正则将会匹配第二个字符,例如$匹配’$’。

\number
引用对应编号的捕获组的内容。组编号从1开始。例如,(.+) \1匹配的是’the the’或’55 55’,但不匹配’the end’。注意反向引用所引用的内容。这个元字符序列只能用来引用1至99之间的一个,如果第一个数字为0,或者是三位数,它不会被解释为反向引用,但会作为8进制数字。在字符组[]里,所有的元字符都被视为字符。

\A
匹配字符串的开始。

\b
匹配空字符串(匹配位置比较容易理解),但只在单词的开头或结尾。一个单词是由字母数字或下划线字符组成,因此一个单词的边界是空白或者非字母数字、不包括下划线。请注意,\b是指\w和\W之间的边界,因此确切的字符集定义取决于UNICODE和LOCALE编译标志的值。在字符范围内,\b表示退格符,与python的字符串兼容。

\B
匹配空字符串(匹配位置比较容易理解),但当它不在单词的开始或结尾。这是和\b相反的,也受到LOCALE和UNICODE的设置影响。

\d
当UNICODE标志没有指定,匹配任何10进制数字,相当于[0-9]。带UNICODE标志时,它会匹配任何在unicode字符集中属于数字分类的字符。

\D
当UNICODE标志没有指定,匹配任何非数字字符,相当于[^0-9]。带UNICODE标志时,它会匹配任何不在unicode字符集中属于数字分类的字符。

\s
当LOCALE和UNICODE标志没有指定时,匹配任何空白字符,这相当于[ \t\n\r\f\v]。带LOCALE标志时,它将匹配当前环境定义的空白符。如果带UNICODE标志,那么将匹配任何被划分为空白符的符号。

\S
当LOCALE和UNICODE标志没有指定时,匹配任何非空白字符,这相当于[^\t\n\r\f\v]。带LOCALE标志时,它将匹配当前环境定义的非空白符。如果带UNICODE标志,那么将匹配任何不被划分为空白符的符号。

\w
当LOCALE和UNICODE标志没有指定时,匹配任何字母数字字符、下划线,这相当于[a-zA-Z0-9_]。带LOCALE标志时,它将匹配当前环境定义的字母和[0-9_]。带UINCODE标志时,将匹配在unicode字符集里划分为字母的字符和[0-9_]。

\W
当LOCALE和UNICODE标志没有指定时,匹配任何非字母数字字符、下划线,这相当于[^a-zA-Z0-9_]。带LOCALE标志时,它将匹配除了当前环境定义的字母、[0-9_]。带UINCODE标志时,将匹配除了在unicode字符集里划分为字母的字符、[0-9_]。

\Z
匹配字符串的结束

原创粉丝点击