Python_正则表达式
一个正则表达式通常被称为一个模式(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次、或多次)。例如,“
0*42”可以匹配42、042、0042、00042等。
- 匹配
- 圆括号可以用来定义操作符的范围和优先度。例如,“
gr(a|e)y”等价于“gray|grey”,“(grand)?father”匹配father和grandfather。
上述这些构造子都可以自由组合,因此,“H(ae?|ä)ndel”和“H(a|ae|ä)ndel”是相同的。
精确的语法可能因不同的工具或程序而异。
| 字符 | 描述 |
|---|---|
| \ | 将下一个字符标记为一个特殊字符(File Format Escape,清单见本表)、或一个原义字符(Identity Escape,有^$()*+?.[\{|共计12个)、或一个向后引用(backreferences)、或一个八进制转义符。例如,“n”匹配字符“n”。“\n”匹配一个换行符。序列“\\”匹配“\”而“\(”则匹配“(”。 |
| ^ | 匹配输入字符串的开始位置。如果设置了RegExp对象的Multiline属性,^也匹配“\n”或“\r”之后的位置。 |
| $ | 匹配输入字符串的结束位置。如果设置了RegExp对象的Multiline属性,$也匹配“\n”或“\r”之前的位置。 |
| * | 匹配前面的子表达式零次或多次。例如,zo*能匹配“z”、“zo”以及“zoo”。*等价于{0,}。 |
| + | 匹配前面的子表达式一次或多次。例如,“zo+”能匹配“zo”以及“zoo”,但不能匹配“z”。+等价于{1,}。 |
| ? | 匹配前面的子表达式零次或一次。例如,“do(es)?”可以匹配“do”或“does”中的“do”。?等价于{0,1}。 |
| {n} | n是一个非负整数。匹配确定的n次。例如,“o{2}”不能匹配“Bob”中的“o”,但是能匹配“food”中的两个o。 |
| {n,} | n是一个非负整数。至少匹配n次。例如,“o{2,}”不能匹配“Bob”中的“o”,但能匹配“foooood”中的所有o。“o{1,}”等价于“o+”。“o{0,}”则等价于“o*”。 |
| {n,m} | m和n均为非负整数,其中n<=m。最少匹配n次且最多匹配m次。例如,“o{1,3}”将匹配“fooooood”中的前三个o。“o{0,1}”等价于“o?”。请注意在逗号和两个数之间不能有空格。 |
| ? | 非贪心量化(Non-greedy quantifiers):当该字符紧跟在任何一个其他重复修饰符(*,+,?,{n},{n,},{n,m})后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串“oooo”,“o+?”将匹配单个“o”,而“o+”将匹配所有“o”。 |
| . | 匹配除“\r”“\n”之外的任何单个字符。要匹配包括“\r”“\n”在内的任何字符,请使用像“(.|\r|\n)”的模式。 |
| (pattern) | 匹配pattern并获取这一匹配的子字符串。该子字符串用于向后引用。所获取的匹配可以从产生的Matches集合得到,在VBScript中使用SubMatches集合,在JScript中则使用$0…$9属性。要匹配圆括号字符,请使用“\(”或“\)”。 |
| (?:pattern) | 匹配pattern但不获取匹配的子字符串(shy groups),也就是说这是一个非获取匹配,不存储匹配的子字符串用于向后引用。这在使用或字符“(|)”来组合一个模式的各个部分是很有用。例如“industr(?:y|ies)”就是一个比“industry|industries”更简略的表达式。 |
| (?=pattern) | 正向肯定预查(look ahead positive assert),在任何匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如,“Windows(?=95|98|NT|2000)”能匹配“Windows2000”中的“Windows”,但不能匹配“Windows3.1”中的“Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。 |
| (?!pattern) | 正向否定预查(negative assert),在任何不匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如“Windows(?!95|98|NT|2000)”能匹配“Windows3.1”中的“Windows”,但不能匹配“Windows2000”中的“Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始 |
| (?<=pattern) | 反向(look behind)肯定预查,与正向肯定预查类似,只是方向相反。例如,“(?<=95|98|NT|2000)Windows”能匹配“2000Windows”中的“Windows”,但不能匹配“3.1Windows”中的“Windows”。 |
| (?<!pattern) | 反向否定预查,与正向否定预查类似,只是方向相反。例如“(?<!95|98|NT|2000)Windows”能匹配“3.1Windows”中的“Windows”,但不能匹配“2000Windows”中的“Windows”。 |
| x|y | 匹配x或y。例如,“z|food”能匹配“z”或“food”。“(?:z|f)ood”则匹配“zood”或“food”。 |
| [xyz] | 字符集合(character class)。匹配所包含的任意一个字符。例如,“[abc]”可以匹配“plain”中的“a”。特殊字符仅有反斜线\保持特殊含义,用于转义字符。其它特殊字符如星号、加号、各种括号等均作为普通字符。脱字符^如果出现在首位则表示负值字符集合;如果出现在字符串中间就仅作为普通字符。连字符 - 如果出现在字符串中间表示字符范围描述;如果如果出现在首位(或末尾)则仅作为普通字符。右方括号应转义出现,也可以作为首位字符出现。 |
| [^xyz] | 排除型字符集合(negated character classes)。匹配未列出的任意字符。例如,“[^abc]”可以匹配“plain”中的“plin”。 |
| [a-z] | 字符范围。匹配指定范围内的任意字符。例如,“[a-z]”可以匹配“a”到“z”范围内的任意小写字母字符。 |
| [^a-z] | 排除型的字符范围。匹配任何不在指定范围内的任意字符。例如,“[^a-z]”可以匹配任何不在“a”到“z”范围内的任意字符。 |
| [:name:] | 增加命名字符类(named character class)[注 1]中的字符到表达式。只能用于方括号表达式。 |
| [=elt=] | 增加当前locale下排序(collate)等价于字符“elt”的元素。例如,[=a=]可能会增加ä、á、à、ă、ắ、ằ、ẵ、ẳ、â、ấ、ầ、ẫ、ẩ、ǎ、å、ǻ、ä、ǟ、ã、ȧ、ǡ、ą、ā、ả、ȁ、ȃ、ạ、ặ、ậ、ḁ、ⱥ、ᶏ、ɐ、ɑ 。只能用于方括号表达式。 |
| [.elt.] | 增加排序元素(collation element)elt到表达式中。这是因为某些排序元素由多个字符组成。例如,29个字母表的西班牙语, "CH"作为单个字母排在字母C之后,因此会产生如此排序“cinco, credo, chispa”。只能用于方括号表达式。 |
| \b | 匹配一个单词边界,也就是指单词和空格间的位置。例如,“er\b”可以匹配“never”中的“er”,但不能匹配“verb”中的“er”。 |
| \B | 匹配非单词边界。“er\B”能匹配“verb”中的“er”,但不能匹配“never”中的“er”。 |
| \cx | 匹配由x指明的控制字符。例如,\cM匹配一个Control-M或回车符。x的值必须为A-Z或a-z之一。否则,将c视为一个原义的“c”字符。 |
| \d | 匹配一个数字字符。等价于[0-9]。注意Unicode正则表达式会匹配全角数字字符。 |
| \D | 匹配一个非数字字符。等价于[^0-9]。 |
| \f | 匹配一个换页符。等价于\x0c和\cL。 |
| \n | 匹配一个换行符。等价于\x0a和\cJ。 |
| \r | 匹配一个回车符。等价于\x0d和\cM。 |
| \s | 匹配任何空白字符,包括空格、制表符、换页符等等。等价于[ \f\n\r\t\v]。注意Unicode正则表达式会匹配全角空格符。 |
| \S | 匹配任何非空白字符。等价于[^ \f\n\r\t\v]。 |
| \t | 匹配一个制表符。等价于\x09和\cI。 |
| \v | 匹配一个垂直制表符。等价于\x0b和\cK。 |
| \w | 匹配包括下划线的任何单词字符。等价于“[A-Za-z0-9_]”。注意Unicode正则表达式会匹配中文字符。 |
| \W | 匹配任何非单词字符。等价于“[^A-Za-z0-9_]”。 |
| \ck | 匹配控制转义字符。k代表一个字符。等价于“Ctrl-k”。用于ECMA语法。 |
| \xnn | 十六进制转义字符序列。匹配两个十六进制数字nn表示的字符。例如,“\x41”匹配“A”。“\x041”则等价于“\x04&1”。正则表达式中可以使用ASCII编码。. |
| \num | 向后引用(back-reference)一个子字符串(substring),该子字符串与正则表达式的第num个用括号围起来的捕捉群(capture group)子表达式(subexpression)匹配。其中num是从1开始的十进制正整数,其上限可能是9[注 2]、31、[注 3]99甚至无限。[注 4]例如:“(.)\1”匹配两个连续的相同字符。 |
| \n | 标识一个八进制转义值或一个向后引用。如果\n之前至少n个获取的子表达式,则n为向后引用。否则,如果n为八进制数字(0-7),则n为一个八进制转义值。 |
| \nm | 3位八进制数字,标识一个八进制转义值或一个向后引用。如果\nm之前至少有nm个获得子表达式,则nm为向后引用。如果\nm之前至少有n个获取,则n为一个后跟文字m的向后引用。如果前面的条件都不满足,若n和m均为八进制数字(0-7),则\nm将匹配八进制转义值nm。 |
| \nml | 如果n为八进制数字(0-3),且m和l均为八进制数字(0-7),则匹配八进制转义值nml。 |
| \un | Unicode转义字符序列。其中n是一个用四个十六进制数字表示的Unicode字符。例如,\u00A9匹配版权符号(©)。 |
Unicode处理[编辑]
在.NET、Java、JavaScript、Python的正则表达式中,可以用\uXXXX表示一个Unicode字符,其中XXXX为四位16进制数字。
Unicode字符的三种性质:[1]
- Unicode Property:字符属于标点、空格、字母等等。每个Unicode字符只能属于唯一Unicode Property。.NET、Java、PHP和Ruby等语言支持。具体分类为:
- 字符\p{L}
- \p{Ll}或\p{Lowercase_Letter}:小写字符(必须有大写的形式)
- \p{Lu}或\p{Uppercase_Letter}: 大写字符(必须有小写的形式)
- \p{Lt}或\p{Titlecase_Letter}: 全词首字母大写的字符
- \p{L&}或\p{Cased_Letter}: 存在大小写形式的字符(Ll, Lu, Lt的组合)
- \p{Lm}或\p{Modifier_Letter}: 音标修饰字符
- \p{Lo}或\p{Other_Letter}: 不具有大小写的字符或字形
- 附加符号\p{M}
- \p{Mn}或\p{Non_Spacing_Mark}: 与其他字符结合,不额外占用空间的字符,例如日耳曼语元音变音
- \p{Mc}或\p{Spacing_Combining_Mark}: 与其他字符结合,不额外占用空间的字符,例如马拉雅拉姆文#元音字母及附标
- \p{Me}或\p{Enclosing_Mark}: 包含其他字符的字符,例如圆圈、方块、
- 分隔符p{Z}
- \p{Zs}或\p{Space_Separator}: a whitespace character that is invisible, but does take up space.
- \p{Zl}或\p{Line_Separator}: line separator character U+2028.
- \p{Zp}或\p{Paragraph_Separator}: paragraph separator character U+2029
- 符号\p{S}
- \p{Sm}或\p{Math_Symbol}: 数学符号
- \p{Sc}或\p{Currency_Symbol}: 通货符号
- \p{Sk}或\p{Modifier_Symbol}: 组合为其他字符的符号
- \p{So}或\p{Other_Symbol}: 其他符号
- 数值字符\p{N}
- 标点符号\p{P}
- 其它符号\p{C}(包括不可见控制字符与未用码位)
- 字符\p{L}
- Unicode Block:按照编码区间划分Unicode字符,每个Unicode Block中的字符编码属于一个编码区间。例如Java语言\p{ InCJK_Compatibility_Ideographs },.NET语言\p{ IsCJK_Compatibility_Ideographs }
- Unicode Script:按照字符所属的书写系统来划分Unicode字符。PHP和Ruby(版本不低于1.9)支持Unicode Script。例如\p{Han}表示汉语(中文字符)。
这三种Unicode性质对应的字符组补集是将开头的\p改为\P,其它不变。
| POSIX字符组 | 说明 | ASCII环境 | Unicode环境 |
|---|---|---|---|
| [:alnum:] | 字母字符和数字字符 | [a-zA-Z0-9] | [\p{L&}\p{Nd}] |
| [:alpha:] | 字母 | [a-zA-Z] | \p{L&} |
| [:ascii:] | ASCII字符 | [\x00-\x7F] | \p{InBasicLatin} |
| [:blank:] | 空格字符和制表符 | [ \t] | [\p{Zs}\t] |
| [:cntrl:] | 控制字符 | [\x00-\x1F\x7F] | \p{Cc} |
| [:digit:] | 数字字符 | [0-9] | \p{Nd} |
| [:graph:] | 空白字符之外的字符 | [\x21-\x7E] | [^\p{Z}\p{C}] |
| [:lower:] | 小写字母字符 | [a-z] | \p{Ll} |
| [:print:] | 类似[:graph:],但包括空白字符 | [\x20-\x7E] | \P{C} |
| [:punct:] | 标点符号 | }~-] | [\p{P}\p{S}] |
| [:space:] | 空白字符 | [ \t\r\n\v\f] | [\p{Z}\t\r\n\v\f] |
| [:upper:] | 大写字母字符 | [A-Z] | \p{Lu} |
| [:word:] | 字母字符 | [A-Za-z0-9_] | [\p{L}\p{N}\p{Pc}] |
| [:xdigit:] | 十六进制字符 | [A-Fa-f0-9] | [A-Fa-f0-9] |
优先权
| 优先权 | 符号 |
|---|---|
| 最高 | \ |
| 高 | ( )、(?: )、(?= )、[ ] |
| 中 | *、+、?、{n}、{n,}、{m,n} |
| 低 | ^、$、中介字符 |
| 次最低 | 串接,即相邻字符连接在一起 |
| 最低 | | |
转义符\
在正则表达式中,有很多有特殊意义的是元字符,比如 \d 和 \s 等,如果要在正则中匹配正常的“\d”而不是“数字”就需要对“\”进行转义,变成“\\”。
在 python 中,无论是正则表达式,还是待匹配的内容,都是以字符串的形式出现的,在字符串中
\ 也有特殊的含义,本身还需要转义。所以如果匹配一次“\d”
| 正则 | 待匹配字符 | 匹配 结果 | 说明 |
| \d | \d | False |
因为在正则表达式中\是有特殊意义的字符,所以要匹配\d本身,用表达式\d无法匹配 |
| \\d | \d | True |
转义\之后变成\\,即可匹配 |
| "\\\\d" | '\\d' | True |
如果在python中,字符串中的'\'也需要转义,所以每一个字符串'\'又需要转义一次 |
| r'\\d' | r'\d' | True |
在字符串之前加r,让整个字符串不转义 |
贪婪匹配:在满足匹配时,匹配尽可能长的字符串,默认情况下,采用贪婪匹配
| 正则 | 待匹配字符 | 匹配 结果 | 说明 |
| <.*> |
<script>...<script> |
<script>...<script> |
默认为贪婪匹配模式,会匹配尽量长的字符串 |
| <.*?> | r'\d' |
<script> <script> |
加上?为将贪婪匹配模式转为非贪婪匹配模式,会匹配尽量短的字符串 |
几个常用的非贪婪匹配Pattern
*? 重复任意次,但尽可能少重复
+? 重复1次或更多次,但尽可能少重复
?? 重复0次或1次,但尽可能少重复
{n,m}? 重复n到m次,但尽可能少重复
{n,}? 重复n次以上,但尽可能少重复
.*?的用法:
. 是任意字符
* 是取 0 至 无限长度
? 是非贪婪模式。
何在一起就是 取尽量少的任意字符,一般不会这么单独写,他大多用在:
.*?x
就是取前面任意长度的字符,直到一个x出现
浙公网安备 33010602011771号