正则表达式为高级的文本模式匹配、抽取或文本形式的搜索和替换功能提供了基础。
简单地说,正则表达式(Regular Expression,简称为 regex)是一些由字符和特殊符号组成的字符串,它们描述了模式的重复或者表述多个字符,因而正则表达式能按照某种模式匹配一系列有类似特征的字符串。换句话说, 它们可以匹配多个字符串……
术语“匹配”(matching),指的是术语“模式匹配”(pattern-matching)。在Python语言的术语中,主要有两种方法完成模式匹配:“搜索”(searching)和“匹配”(matching)。搜索即在字符串任意部分中搜索匹配的模式;而匹配是指判断一个字符串可否从起始处所有或者部分地匹配某个模式。搜索经过search()
函数或方法来实现,而匹配经过调用match()
函数或方法实现。总之,当涉及模式时,所有使用术语“匹配”。php
第一部分供快速查阅,正则表达式在Python中的用法在第二部分介绍。python
^
、$
、*
、+
、?
、.
、|
、\
、(
、)
、{
、}
、[
、]
?
、+
、*
、{n}
、{n,m}
、{n,}
[]
来构建一个简单的类。^
[0-9a-b]
字符 | 等价类 |
---|---|
. |
[^\r\n] |
\d |
[0-9] |
\D |
[^0-9] |
\s |
[\t\n\r\f\v] |
\S |
[^\t\n\r\f\v] |
\w |
[a-zA-Z0-9_] |
\W |
[^a-zA-Z0-9_] |
^
、$
、\b
、\B
^
、$
分别表明串开始和串结束\b
、\B
分别表明单词边界和费单词边界()
、|
先来看几个使用字符串方法的例子:web
# 字符串匹配就能实现 # 场景1. 找到course开头的语句 def find_start_str(file_name, start_str): file = open(file_name) for line in file: if line.startswith(start_str): print(line) file.close() find_start_str('course.txt', 'course') # 场景2, 找到course开头和2019结尾的语句 def find_start_end_str(file_name, start_str, end_str): file = open(file_name) for line in file: if line.startswith(start_str)\ and line[:-1].endswith(end_str): # Python是以\n结束的 print(line) file.close() find_start_end_str('course.txt', 'course', '2019') # 场景3,匹配一个下划线或者字母开头的变量名 a = "_valuel" print(a and(a[0] == '_' or 'a' <= a[0] <= 'Z'))
course.txt
文件:正则表达式
course Java 2019 course Html 2018 course Python 2010 course C++ 2018 course Python3 2019 C 0000 C# 0000 .net 0000 php 0000
问题:每一次匹配都要单独写函数完成,有没有相应简单的方法?express
re.Match
Match
对象是一次匹配的结果,包含了不少关于这次匹配的信息,可使用Match
提供的可读属性或方法来获取这些信息。python3.x
属性:app
endpos
:The index into the string beyond which the RE engine will not go.文本中正则表达式结束搜索的索引。值与Pattern.match()和Pattern.seach()方法的同名参数相同。lastgroup
:The name of the last matched capturing group.最后一个被捕获的分组的别名。若是这个分组没有别名或者没有被捕获的分组,将为None。lastindex
:The integer index of the last matched capturing group.最后一个被捕获的分组在文本中的索引。若是没有被捕获的分组,将为None。pos
:The index into the string at which the RE engine started looking for a match.文本中正则表达式开始搜索的索引。值与Pattern.match()和Pattern.seach()方法的同名参数相同。re
:The regular expression object.匹配时使用的Pattern对象。regs
:string
:The string passed to match() or search().匹配时使用的文本。方法:ide
end(self, group=0, /)
expand(self, /, template)
group(...)
groupdict(self, /, default=None)
groups(self, /, default=None)
span(self, group=0, /)
start(self, group=0, /)
更多请查阅:help(re.Match)
svg
re.Pattern
对象Pattern
对象是一个编译好的正则表达式,经过Pattern
提供的一系列方法能够对文本进行匹配查找。
Pattern
不能直接实例化,必须使用re.compile()
进行构造。函数
Pattern
提供了几个可读属性用于获取表达式的相关信息:
flags
:The regex matching flags.编译时用的匹配模式。数字形式。groupindex
:A dictionary mapping group names to group numbers. 以表达式中有别名的组的别名为键、以该组对应的编号为值的字典,没有别名的组不包含在内。groups
:The number of capturing groups in the pattern.表达式中分组的数量。pattern
:The pattern string from which the RE object was compiled.编译时用的表达式字符串。更多请查阅:help(re.Pattern)
>ipython In [1]: import re In [3]: type(re.compile(r'course')) Out[3]: re.Pattern In [4]: In [4]: re.match(r'course','course Python3.x').group() Out[4]: 'course'
>ipython In [1]: str = 'course python 2019' In [2]: str.find('one') Out[2]: -1 In [3]: str.find('py') Out[3]: 7 In [4]: str.startswith('python') Out[4]: False In [5]: str.startswith('course') Out[5]: True In [6]: import re In [7]: pa = re.compile(r'2019\n') In [8]: type(pa) Out[8]: re.Pattern In [9]: re.Pattern. findall() fullmatch() match() scanner() sub() finditer() groupindex mro() search() subn() flags groups pattern split() In [9]: help(re.Pattern.match) Help on method_descriptor: match(self, /, string, pos=0, endpos=9223372036854775807) Matches zero or more characters at the beginning of the string. In [10]:
注:r
表明原始字符串
,最大的做用是避免转义
Match对象的属性
>>> m = re.match(r'\d+','456abc') >>> m.string '456abc'
>>> m <_sre.SRE_Match object at 0x02C8FA68> >>> m.re <_sre.SRE_Pattern object at 0x02D4ECD0>
>>> m.pos 0
>>> m.endpos 6
>>> m= re.match(r'a(b)(c)d','abcdef') >>> m.lastindex 2
lastgroup属性:
该属性表示最后一个被捕获的分组别名。若是这个分组没有别名或者没有被捕获的分组,将为None。
group([group1, …]):
得到一个或多个分组截获的字符串;指定多个参数时将以元组形式返回。group1可使用编 号也可使用别名;编号0表明匹配的整个子串;默认返回group(0)
实例:group函数传多个参数
p = re.compile('(a(b)c)d') m = p.match('abcd') resTup = m.group(1,2,1) print resTup >>>('abc', 'b', 'abc')
groups([default=None])
以元组形式返回所有分组截获的字符串。至关于调用group(1,2,…last)
start([group=0])
返回指定的组截获的子串在string中的起始索引(子串第一个字符的索引)。默认为第0组,即整个字符串
end([group=0])
返回指定的组截获的子串在string中的结束索引(子串最后一个字符的索引)。group默认值 为0,即整个字符串
span([group])
该方法表示以元组的形式返回 (start(group), end(group)),即某个分组的匹配文字内容在被 匹配字符串的开始索引位置和结束索引位置
expand(template)
将匹配到的分组代入template中而后返回。template中可使用\id或\g、\g 引用分组,但不能使用编号0。\id与\g是等价的;但\10将被认为是第10个分组,若是 你想表达\1以后是字符’0’,只能使用\g<1>0。
m = re.search(r'(\w+)! (\w+) (\w+)','HMan! How finny!') # 将匹配的结果带入 print m.expand(r'resut:\3 \2 \1') >>> resut:finny How HMan
>>> m = re.search(r'(?P<num>\d+)(\w+)','78fd') >>> m.groupdict() {'num': '78'}
match()方法
- 匹配字符串开头的零个或多个字符。返回一个match对象或None。
- 可选参数pos和endpos分别指定被匹配字符串的开始和结束位置
In [10]: str Out[10]: 'course python 2019' In [11]: pa.match(str) Out[11]: <re.Match object; span=(0, 6), match='course'> In [12]: ma = pa.match(str) In [13]: ma Out[13]: <re.Match object; span=(0, 6), match='course'> In [14]: type(ma) In [15]: re.Match. end() group() lastgroup pos span() endpos groupdict() lastindex re start() expand() groups() mro() regs string In [15]: ma.group() Out[15]: 'course' In [16]: help(re.Match.group) Help on method_descriptor: group(...) group([group1, ...]) -> str or tuple. Return subgroup(s) of the match by indices or names. For 0 returns the entire match. In [17]:
group()方法
- 返回一个字符串或者元组
- 有括号括起来返回元组,不然返回字符串
匹配结果在原始字符串的索引位置:span()
方法
In [17]: ma.span() Out[17]: (0, 6) In [18]:
被匹配字符串:string
属性
In [18]: ma.string Out[18]: 'course python 2019'
Pattern实例:re
属性
In [19]: ma.re Out[19]: re.compile(r'course', re.UNICODE) In [20]:
忽略大小写:
In [20]: pa Out[20]: re.compile(r'course', re.UNICODE) In [21]: pa = re.compile('course', re.I) In [22]: pa Out[22]: re.compile(r'course', re.IGNORECASE|re.UNICODE) IIn [23]: ma = pa.match('Course: Python3.x \n course:etc...') In [24]: ma.group() Out[24]: 'Course' In [25]: ma = pa.match('Couse: Python3.x \n course:etc...') In [26]: ma.group() --------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-8-ad89060ab833> in <module> ----> 1 ma.group() AttributeError: 'NoneType' object has no attribute 'group' In [27]: pa = re.compile('course') In [28]: pa Out[28]: re.compile(r'course', re.UNICODE) In [29]: ma = pa.match('Couse: Python3.x \n course:etc...') In [30]: ma.group() --------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-18-ad89060ab833> in <module> ----> 1 ma.group() AttributeError: 'NoneType' object has no attribute 'group' In [31]:
以(元)组
的形式返回groups()
:
In [31]: pa = re.compile(r'(course)', re.I) In [32]: pa Out[32]: re.compile(r'(course)', re.IGNORECASE|re.UNICODE) In [33]: pa.match('Course: Python3.x \n course:etc...').group() Out[33]: 'Course' In [34]: pa.match('Course: Python3.x \n course:etc...').groups() Out[34]: ('Course',) In [35]: pa = re.compile(r'course', re.I) In [36]: pa Out[36]: re.compile(r'course', re.IGNORECASE|re.UNICODE) In [37]: pa.match('Course: Python3.x \n course:etc...').group() Out[37]: 'Course' In [38]: pa.match('Course: Python3.x \n course:etc...').groups() Out[38]: () In [39]: pa = re.compile(r'course', re.I) In [40]: pa Out[40]: re.compile(r'course', re.IGNORECASE|re.UNICODE) In [41]: pa.match('Course: Python3.x \n course:etc...').group() Out[41]: 'Course' In [42]: pa.match('Course: Python3.x \n course:etc...').groups() Out[42]: () In [43]: pa = re.compile(r'(course)', re.I) In [44]: pa Out[44]: re.compile(r'(course)', re.IGNORECASE|re.UNICODE) In [45]: pa.match('Course: Python3.x \n course:etc...').group() Out[45]: 'Course' In [46]: pa.match('Course: Python3.x \n course:etc...').groups() Out[46]: ('Course',) In [47]:
关于groups()
In [52]: ma = pa.match('Course: Python3.x \n course:etc...') In [53]: ma Out[53]: <re.Match object; span=(0, 6), match='Course'> In [54]: type(ma) Out[54]: re.Match In [55]: help(re.Match.groups) Help on method_descriptor: groups(self, /, default=None) Return a tuple containing all the subgroups of the match, from 1. default Is used for groups that did not participate in the match. In [56]:
上面方法是先生成判断对象再匹配字符串。下面介绍直接使用match方法:
直接使用match方法
In [56]: help(re.match) Help on function match in module re: match(pattern, string, flags=0) Try to apply the pattern at the start of the string, returning a Match object, or None if no match was found. In [57]:
match()
方法
- 尝试应用字符串开头的模式,返回匹配对象,若是没有找到匹配,则返回None。
In [57]: ma = re.match(r'course','course python3.x etc..') In [58]: ma Out[58]: <re.Match object; span=(0, 6), match='course'> In [59]: type(ma) Out[59]: re.Match In [60]: ma.group() Out[60]: 'course' In [61]:
注:这种方式适合匹配次数较少的状况,由于每次匹配都会生成一个Pattern对象。
In [10]: re. A copyreg enum findall functools L Match Pattern S split sub TEMPLATE UNICODE ASCII DEBUG error finditer I LOCALE match purge Scanner sre_compile subn template VERBOSE compile DOTALL escape fullmatch IGNORECASE M MULTILINE RegexFlag search sre_parse T U X In [10]: str Out[10]: 'course python 2019' In [11]: pa = re.compile(r'2019') In [12]: pa.match(str) In [13]: pa.search(str) Out[13]: <re.Match object; span=(14, 18), match='2019'> In [14]: sc = pa.search(str) In [15]: sc.group Out[15]: <function Match.group> In [16]: sc.group() Out[16]: '2019' In [17]: pa = re.compile(r'course') In [18]: pa.match(str).group() Out[18]: 'course' In [22]: help(sc.group) Help on built-in function group: group(...) method of re.Match instance group([group1, ...]) -> str or tuple. Return subgroup(s) of the match by indices or names. For 0 returns the entire match. In [23]:
字符 | 匹配 |
---|---|
. |
匹配任意(除\n )字符 |
[] |
匹配[] 中包含字符串中任一字符 |
\d ,\D |
匹配数字,非数字 |
\s ,\S |
匹配空白(\t 、\n 、\r 、\f 、\v ),非空白字符 |
\w ,\W |
匹配单词字符[a-zA-Z0-9_] ,非单词字符 |
注:
[...]
匹配的是[]中包含字符的任意一个字符,如[ijk]匹配的是i、j、k任一字符;匹配多个字符的状况详下面。[\u4E00-\u9FA5]
匹配任一汉字,英文空格不是汉字。[.]
匹配的是.
,再如[.*]匹配的是.
或*
[\d]
匹配的是任意数字,等价于[0-9]
[^...]
中的^
表示字符类取反\t
、\n
、\r
、\f
、\v
分别对应:水平制表符、换行符、回车符、换页符、垂直制表符In [3]: import re In [4]: ma = re.match(r'{[abc]}','{b}') In [5]: ma.group() Out[5]: '{b}' In [6]: ma = re.match(r'{[abc]}','{d}') In [7]: type(ma) Out[7]: NoneType In [8]: ma = re.match(r'{[.]}','{d}') In [9]: ma.group() --------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-9-ad89060ab833> in <module> ----> 1 ma.group() AttributeError: 'NoneType' object has no attribute 'group' In [10]: ma = re.match(r'{.}','{d}') In [11]: ma.group() Out[11]: '{d}' In [16]: ma = re.match(r'{\[[abcd]\]}','{[d]}') In [17]: ma.group() Out[17]: '{[d]}' In [18]:
注:若是要匹配的模式包含[]
须要转义.
字符 | 匹配 |
---|---|
* |
匹配前一个元素0次或者无限次 |
+ |
匹配前一个元素1次或者无限次 |
? |
匹配前一个元素0次或者1次,非贪婪 |
{m} /{m,n} /{m,} |
匹配前一个元素刚好m次或者至少m次但很少于n次或者至少m次 |
*? /+? /?? |
匹配模式变为非贪婪(尽量少匹配字符) |
In [18]: ma = re.match(r'[A-Z][a-z]*','A') In [19]: ma.group() Out[19]: 'A' In [20]: ma = re.match(r'[A-Z][a-z]','A') In [21]: ma.group() --------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-21-ad89060ab833> in <module> ----> 1 ma.group() AttributeError: 'NoneType' object has no attribute 'group' In [22]: ma = re.match(r'[A-Z][a-z]*','AbcdefgHIJK') In [23]: ma.group() Out[23]: 'Abcdefg' In [24]:
一个例子:
Python变量命名规则
- 变量名只能包含字母、数字和下划线。变量名能够字母或下划线开头,但不能以数字开头。
- 变量名不能包含空格,但可以使用下划线来分隔其中的单词。
- 不要将Python关键字和函数名用做变量名,即不要使用Python保留用于特殊用途的单词,如print。
- 变量名应既简短又具备描述性。
- 慎用小写字母l和大写字母O,因给他们可能被人错当作数字1和0;
注意:应使用小写的Python变量名。在变量名中使用大写字母虽然不会致使错误,但避免使用大写字母是个不错的注意。
咱们重点关注前两点,用正则表达式来描述:
In [38]: while(True): ...: pa = re.compile(r'[_a-zA-Z][_\w]*') ...: str = input("输入字符串:") ...: ma = pa.match(str) ...: if ma != None: ...: print(ma.group()) ...: In [44]: while(True): ...: pa = re.compile(r'[_a-zA-Z][_a-zA-Z0-9]*') ...: str = input("输入:") ...: ma = pa.match(str) ...: if ma != None: ...: print(ma.group()) ...:
44是对38的改进,能够尝试38输入__哈哈
仍然匹配成功,而44中匹配获得的是__
匹配0-99之间的数字:
In [5]: ma = re.match(r'[1-9]?[0-9]', '0') In [6]: ma.group() Out[6]: '0' In [7]: ma = re.match(r'[1-9]?[0-9]', '10') In [8]: ma.group() Out[8]: '10' In [9]: ma = re.match(r'[1-9]?[0-9]', '99') In [10]: ma.group() Out[10]: '99' In [11]: ma = re.match(r'[1-9]?[0-9]', '100') In [12]: ma.group() Out[12]: '10' In [13]:
匹配指定次数:
In [21]: re.match(r'[a-z]{2}','haha').group() Out[21]: 'ha' In [22]: re.match(r'[a-z]{2,3}','haha').group() Out[22]: 'hah' In [23]: re.match(r'[a-z]{2,4}','hahaxxxioflsaj').group() Out[23]: 'haha' In [24]: re.match(r'[a-z]{2,4}','ha3ha').group() Out[24]: 'ha' In [25]: re.match(r'[a-z]{2,4}','hah3ha').group() Out[25]: 'hah' In [26]: re.match(r'[a-z]{2,4}','hahx3ha').group() Out[26]: 'hahx' In [27]:
非贪婪模式:*?
、+?
、??
In [28]: ma = re.match(r'[0-9][a-z]*','1abcdef').group() In [29]: re.match(r'[0-9][a-z]*','1abcdef').group() Out[29]: '1abcdef' In [30]: re.match(r'[0-9][a-z]*?','1abcdef').group() Out[30]: '1' In [31]: re.match(r'[0-9][a-z]+?','1abcdef').group() Out[31]: '1a' In [32]: re.match(r'[0-9][a-z]?','1abcdef').group() Out[32]: '1a' In [33]: re.match(r'[0-9][a-z]+','1abcdef').group() Out[33]: '1abcdef' In [34]: re.match(r'[0-9][a-z]??','1abcdef').group() Out[34]: '1' In [35]: re.match(r'[0-9][a-z]?','1abcdef').group() Out[35]: '1a' In [36]:
贪婪匹配的限定符:*
、+
、?
、{n}
、{n,}
、{n,m}
非贪婪是在贪婪限定符后面多加一个?
,以下表所示:
限定符 | 描述 | 模式 | 匹配 |
---|---|---|---|
*? |
匹配上一个元素零次或屡次,但次数尽量少 | \d*?\.\d |
“.0”,“19.9"和"219.9” |
+? |
匹配上一个元素一次或屡次,但次数尽量少 | be+? |
“been中的"be”,bent"中的"be" |
?? |
匹配上一个元素零次或一次,但次数尽量少 | rai??n |
“ran"和"rain” |
{n}? |
匹配前导元素刚好n次 | ,\d{3}? |
"1.043.6"中的.043 |
{n,}? |
匹配上一个元素至少n次,但次数尽量少 | \d{2,}? |
“166”,“29"和"1930” |
{n,m}? |
匹配上一个元素的次数介于n和m之间,但次数尽量少 | \d{3,5}? |
“166”,“16546”,“132654"中的"132”,“654” |
测试代码:
import re line = "" regex_re = "" match_obj = re.match(regex_re, line) if match_obj: print("# line = \"%s\"" % line) print("# regex_re = \"%s\"" % (regex_re,)) print("# 贪婪以后:match_obj.group(1)->%s" % match_obj.group(1)) # print("# match_obj.group()->%s" % match_obj.group())
验证:
line = "boooooooobaaaaaoooooobbbbbaaabby123" regex_re = ".*(b.*b).*" # 贪婪:match_obj.group(1)->bb match_obj.group()->boooooooobaaaaaoooooobbbbbbby123 line = "boooooooobaaaaaoooooobbbbbbby123" regex_re = ".*(b.+b).*" # 贪婪:match_obj.group(1)->bbb match_obj.group()->boooooooobaaaaaoooooobbbbbbby123 line = "booooboooooobbbbbbaaaby123" regex_re = ".*(b.*b).*" # 贪婪:match_obj.group(1)->baaab match_obj.group()->booooboooooobbbbbbaaaby123 line = "booooboooooobbbbbbaaaby123" regex_re = ".*(b.+b).*" # 贪婪:match_obj.group(1)->baaab match_obj.group()->booooboooooobbbbbbaaaby123 line = "boooobaaaooobbbaaaaaaby123" regex_re = ".*(b.{2,5}b).*" # 贪婪:match_obj.group(1)->boooob match_obj.group()->boooobaaaooobbbaaaaaaby123 line = "o你f" regex_re = "(^o[\w]?f$)" # 贪婪:match_obj.group(1)->o你f # 注:group提取的是最外边那个括号 line = "boobby123" regex_re = "((bobby|boobby)123)" # 贪婪:match_obj.group(1)->boobby123 line = "study in 四川大学" regex_re = ".*([一-龥]+大学)" # 贪婪:match_obj.group(1)->川大学 line = "study in 四川大学" regex_re = ".*?([一-龥]+大学)" # 非贪婪:match_obj.group(1)->四川大学 line = "of 出生于 1996年" regex_re = ".*?([\d]+)" # 非贪婪:match_obj.group(1)->1996 line = "of 出生于 1996年" regex_re = ".*?(\d+)" # 非贪婪:match_obj.group(1)->1996 line = "booooooooobby123" regex_re = ".*(b.*b).*" # 贪婪:match_obj.group(1)->bb line = "booooooooobby123" regex_re = ".*?(b.*b).*" # 前非贪婪后贪婪:match_obj.group(1)->booooooooobb line = "booooooooobby123" regex_re = ".*?(b.*?b).*" # 非贪婪:match_obj.group(1)->booooooooob line = "booooooooobby123" regex_re = ".*(b.*?b).*" # 前贪婪后非贪婪:match_obj.group(1)->bb line = "booooooooobijkby123" regex_re = ".*(b.*?b).*" # 前贪婪后非贪婪:match_obj.group(1)->bijkb
字符 | 匹配 |
---|---|
^ | 匹配字符串开头 |
$ | 匹配字符串结尾 |
\A/\Z | 指定字符串必须出如今开头/结尾 |
问题引入:
In [37]: re.match(r'[a-zA-Z]{4,10}@onefine.top','123coding@onefine.top123').group() --------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-37-5c2cf60a1190> in <module> ----> 1 re.match(r'[a-zA-Z]{4,10}@onefine.top','123coding@onefine.top123').group() AttributeError: 'NoneType' object has no attribute 'group' In [38]: re.search(r'[a-zA-Z]{4,10}@onefine.top','123coding@onefine.top123').group() Out[38]: 'coding@onefine.top' In [39]: re.search(r'^[a-zA-Z]{4,10}@onefine.top$','123coding@onefine.top123').group() --------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-39-70e4e4e6988c> in <module> ----> 1 re.search(r'^[a-zA-Z]{4,10}@onefine.top$','123coding@onefine.top123').group() AttributeError: 'NoneType' object has no attribute 'group' In [40]: re.search(r'^[a-zA-Z]{4,10}@onefine.top','123coding@onefine.top123').group() --------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-40-3c138c9aac5e> in <module> ----> 1 re.search(r'^[a-zA-Z]{4,10}@onefine.top','123coding@onefine.top123').group() AttributeError: 'NoneType' object has no attribute 'group' In [41]: re.search(r'^[a-zA-Z]{4,10}@onefine.top$','123coding@onefine.top').group() --------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-41-4ca35adfb0df> in <module> ----> 1 re.search(r'^[a-zA-Z]{4,10}@onefine.top$','123coding@onefine.top').group() AttributeError: 'NoneType' object has no attribute 'group' In [42]: re.search(r'^[a-zA-Z]{4,10}@onefine.top$','coding@onefine.top').group() Out[42]: 'coding@onefine.top' In [43]: re.match(r'^[a-zA-Z]{4,10}@onefine.top$','coding@onefine.top').group() Out[43]: 'coding@onefine.top' In [45]: re.match(r'^[a-zA-Z]{4,10}@onefine.top','coding@onefine.top123').group() Out[45]: 'coding@onefine.top' In [46]:
\A/\Z 指定字符串必须出如今开头/结尾,用法
指定必须以coding开头,top结尾
In [52]: re.match(r'\A(coding)[\w]*@onefine.(top)\Z','coding@onefine.top').group() Out[52]: 'coding@onefine.top' In [53]:
字符 | 匹配 |
---|---|
| |
匹配左右任意一个表达式 |
(ab) | 括号中表达式做为一个分组 |
\<number> |
引用编号为number的分组匹配到的字符串,编号从1开始 |
(?P<name>) |
分组起一个别名name |
(?P=name) | 引用别名为name的分组匹配字符串 |
In [54]: re.match(r'abc|d','d').group() Out[54]: 'd' In [55]: re.match(r'abc|d','abc').group() Out[55]: 'abc' In [56]: re.match(r'abc|d','c').group() --------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-56-dfcd4a662ebe> in <module> ----> 1 re.match(r'abc|d','c').group() AttributeError: 'NoneType' object has no attribute 'group' In [57]:
匹配0-100的字符串:
In [57]: re.match(r'[1-9]?\d$|100','100').group() Out[57]: '100' In [58]: re.match(r'[1-9]?\d$|100','99').group() Out[58]: '99' In [59]: re.match(r'[1-9]?\d$|100','1').group() Out[59]: '1' In [60]: re.match(r'[1-9]?\d$|100','0').group() Out[60]: '0' In [61]:
匹配多邮箱:
n [63]: re.match(r'[\w]{4,8}@(163|126).com','onefine@126.com').group() Out[63]: 'onefine@126.com' In [64]: re.match(r'[\w]{4,8}@(163|126).com','onefine@163.com').group() Out[64]: 'onefine@163.com' In [65]: re.match(r'[\w]{4,8}@(163|126).com','onefine@963.com').group() --------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-65-afd701da2fb6> in <module> ----> 1 re.match(r'[\w]{4,8}@(163|126).com','onefine@963.com').group() AttributeError: 'NoneType' object has no attribute 'group' In [66]:
XML–引用分组
In [80]: re.match(r'<([\w]+>)[\w]+<\\\1','<img>onefine<\img>').group() Out[80]: '<img>onefine<\\img>' In [81]: re.match(r'<([\w]+>)[\w]+</\1','<img>onefine</img>').group() Out[81]: '<img>onefine</img>' In [82]:
80写错了,注意上面的\\
是转义\
;
正确的是81,可是有了新的发现:
先看个例子:
import re string = '3\8' m = re.search('(\d+)\\\\', string) if m is not None: print m.group(1) # 结果为:3 n = re.search(r'(\d+)\\', string) if n is not None: print n.group(1) # 结果为:3
正则表达式字符串须要通过两次转义,这两次分别是上面的“字符串转义”和“正则转义”,我的认为“字符串转义”必定先于“正则转义”。
1)
'\\\\'
的过程:
先进行“字符串转义”,前两个反斜杠和后两个反斜杠分别被转义成了一个反斜杠;即“\\|\\”
被转成了“\|\”
(“|”为方便看清,请自动忽略)。“字符串转义”后立刻进行“正则转义”,“\\”
被转义为了“\”
,表示该正则式须要匹配一个反斜杠。2)
r'\\'
的过程:
因为原始字符串中全部字符直接按照字面意思来使用,不转义特殊字符,故不作“字符串转义”,直接进入第二步“正则转义”,在正则转义中“\\”
被转义为了“\”
,表示该正则式须要匹配一个反斜杠。结论:也就是说原始字符串(即
r'...'
)与“正则转义”毫无关系,原始字符串仅在“字符串转义”中起做用,使字符串免去一次转义。
分组起别名&引用,即最后两个成对使用:
In [97]: re.match(r'<(?P<mark>[\w]+>)[\w]+</(?P=mark)','<img>onefine</img>').group() Out[97]: '<img>onefine</img>'
模块re中一些重要的函数
函数 | 描述 |
---|---|
compile(pattern[, flags]) |
根据包含正则表达式的字符串建立模式对象 |
search(pattern, string[,flags]) |
在字符串中查找模式 |
match(pattern, string[,flags]) |
在字符串开头匹配模式 |
split(pattern, string[,maxsplit=0]) |
根据模式来分割字符串 |
findall(pattern, string) |
返回一个列表, 其中包含字符串中全部与模式匹配的子串 |
sub(pat, repl, string[,count=0]) |
将字符串中与模式pat匹配的子串都替换为repl |
escape(string) |
对字符串中全部的正则表达式特殊字符都进行转义 |
C:\Users\ONEFINE>ipython Python 3.7.1 (v3.7.1:260ec2c36a, Oct 20 2018, 14:57:15) [MSC v.1915 64 bit (AMD64)] Type 'copyright', 'credits' or 'license' for more information IPython 7.2.0 -- An enhanced Interactive Python. Type '?' for help. In [1]: import re In [2]: help(re.match) Help on function match in module re: match(pattern, string, flags=0) Try to apply the pattern at the start of the string, returning a Match object, or None if no match was found.
In [3]: help(re.search) Help on function search in module re: search(pattern, string, flags=0) Scan through string looking for a match to the pattern, returning a Match object, or None if no match was found.
search()方法:
- 扫描字符串string,查找模式pattern指定的正则表达式模式,产生匹配的第一个位置,返回相应的Match对象实例,若是字符串中没有位置与模式匹配,则返回None。请注意,这与在字符串中的某处找到零长度匹配不一样。
In [4]: help(re.findall) Help on function findall in module re: findall(pattern, string, flags=0) Return a list of all non-overlapping matches in the string. If one or more capturing groups are present in the pattern, return a list of groups; this will be a list of tuples if the pattern has more than one group. Empty matches are included in the result.
findall()方法
- 返回的全部非重叠的匹配模式 的字符串,如字符串列表。该字符串进行扫描左到右,并匹配以发现的顺序返回。若是模式中存在一个或多个组,返回组列表; 若是模式有多个组,这将是一个元组列表。空结果包含在结果中,除非他们触及另外一场比赛的开始。
例子:
In [15]: re.search(r':\d+','Python3.x:4000 C++:5000 JAVA:4800').group()[1:] Out[15]: '4000' In [18]: re.findall(r':\d+','Python3.x:4000 C++:5000 JAVA:4800') Out[18]: [':4000', ':5000', ':4800'] In [19]:
In [5]: help(re.compile) Help on function compile in module re: compile(pattern, flags=0) Compile a regular expression pattern, returning a Pattern object.
In [6]: help(re.split) Help on function split in module re: split(pattern, string, maxsplit=0, flags=0) Split the source string by the occurrences of the pattern, returning a list containing the resulting substrings. If capturing parentheses are used in pattern, then the text of all groups in the pattern are also returned as part of the resulting list. If maxsplit is nonzero, at most maxsplit splits occur, and the remainder of the string is returned as the final element of the list.
split()方法
- 根据模式的出现拆分字符串。若是在模式中使用捕获括号,则模式中全部组的文本也会做为结果列表的一部分返回。
- 若是maxsplit不为零,则最多发生maxsplit分割,而且字符串的其他部分做为列表的最后一个元素返回。
例子:
In [50]: str_2 = "course: Python C C++ C# JAVA,etc" In [51]: re.split(r':| |,',str_2) Out[51]: ['course', '', 'Python', 'C', 'C++', 'C#', 'JAVA', 'etc'] In [52]: re.split(r' :| |,',str_2) Out[52]: ['course:', 'Python', 'C', 'C++', 'C#', 'JAVA', 'etc'] In [53]:
In [7]: help(re.sub) Help on function sub in module re: sub(pattern, repl, string, count=0, flags=0) Return the string obtained by replacing the leftmost non-overlapping occurrences of the pattern in string by the replacement repl. repl can be either a string or a callable; if a string, backslash escapes in it are processed. If it is a callable, it's passed the Match object and must return a replacement string to be used.
sub()方法
- 经过用替换repl替换字符串中最左边不重叠出现的模式而得到的字符串。 若是未找到该模式,则字符串将保持不变。 repl能够是一个字符串或一个函数; 若是它是一个字符串,则处理其中的任何反斜杠转义。 也就是\ n被转换为单个换行符,
\ r
被转换为回车符,等等。 像\ j这样的未知转义字符将被单独保留。 反向引用(例如\ 6)被替换为模式中由组6匹配的子字符串。
repl为字符串的例子:
In [24]: str = "course Python videonum: 1000" In [25]: re.sub(r'\d+','9631', str) Out[25]: 'course Python videonum: 9631' In [26]:
与分组一块儿用:
In [23]: re.sub(r'def\s+([a-zA-Z_][a-zA-Z_0-9]*)\s*\(\s*\):',r'static PyObject*\npy_\1(void)\n{','def myfunc():') Out[23]: 'static PyObject*\npy_myfunc(void)\n{'
repl为函数的例子:
In [43]: def add(match): ...: val = match.group() ...: num = int(val) + 1 ...: return str(num) ...: ...: In [44]: str Out[44]: 'course Python videonum: 1000' In [45]: del(str) In [46]: str_1 = 'course Python videonum: 1000' In [48]: re.sub(r'\d+', add, str_1) Out[48]: 'course Python videonum: 1001' In [49]:
提示:str是Python内置函数。千万不要定义为变量名。错误TypeError: ‘str’ object is not callable字面上意思:就是str不能够被系统调用,其实缘由就是:你正在调用一个不能被调用的变量或对象,具体表现就是你调用函数、变量的方式错误。
In [8]: help(re.escape) Help on function escape in module re: escape(pattern) Escape special characters in a string. In [10]: help(re.I) Help on RegexFlag in module re object: class RegexFlag(enum.IntFlag) | RegexFlag(value, names=None, *, module=None, qualname=None, type=None, start=1) | | An enumeration. | | Method resolution order: | RegexFlag | enum.IntFlag | builtins.int | enum.Flag | enum.Enum | builtins.object | | Data and other attributes defined here: | | ASCII = <RegexFlag.ASCII: 256> | | DEBUG = <RegexFlag.DEBUG: 128> | | DOTALL = <RegexFlag.DOTALL: 16> | | IGNORECASE = <RegexFlag.IGNORECASE: 2> | | LOCALE = <RegexFlag.LOCALE: 4> | | MULTILINE = <RegexFlag.MULTILINE: 8> | | TEMPLATE = <RegexFlag.TEMPLATE: 1> | | UNICODE = <RegexFlag.UNICODE: 32> | | VERBOSE = <RegexFlag.VERBOSE: 64> | | ---------------------------------------------------------------------- | Data descriptors inherited from enum.Enum: | | name | The name of the Enum member. | | value | The value of the Enum member. | | ---------------------------------------------------------------------- | Data descriptors inherited from enum.EnumMeta: | | __members__ | Returns a mapping of member name->value. | | This mapping lists all enum members, including aliases. Note that this | is a read-only view of the internal mapping. In [11]:
正则表达式能够包含一些标志修饰符来控制匹配模式,用在正则表达式处理函数中的flag参数中,为可选参数。
标志 | 描述 |
---|---|
re.I(IGNORECASE) | 忽略大小写 |
re.M(MULTILINE) | 多行模式,改变’^‘和’$'的行为 |
re.S(DOTALL) | 改变’.'的行为 |
re.X(VERBOSE) | 能够给你的表达式写注释 |
注:
>ipython In [1]: str_1 = 'Hello world' In [2]: import re In [3]: re.search(r'wo..d', str_1, re.I|re.M).group() Out[3]: 'world' In [4]:
In [1]: import re In [2]: re.search('a','abc').group() Out[2]: 'a' In [3]: re.search('a','Abc').group() --------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-3-94da83bf8997> in <module> ----> 1 re.search('a','Abc').group() AttributeError: 'NoneType' object has no attribute 'group' In [4]: re.search('a','Abc',re.I).group() Out[4]: 'A' In [5]:
^
和$
的行为In [6]: re.search('foo.$', 'foo2\nfoo3\n').group() Out[6]: 'foo3' In [7]: re.search('foo.$', 'foo2\nfoo3\n', re.M).group() Out[7]: 'foo2' In [8]:
疑问:$不包括换行??? 加了M以后匹配第一行的结尾
.
的行为,使点.
匹配包括换行在内的全部字符- make the '.' special character match any character at all, including a newline; without flag, '.' will match anything except a newline.
In [15]: re.search('.', '\n').group() --------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-15-d4cd05f33b46> in <module> ----> 1 re.search('.', '\n').group() AttributeError: 'NoneType' object has no attribute 'group' In [16]: re.search('.', '\n', re.S).group() Out[16]: '\n' In [17]:
注:加S能够匹配包括换行符在内的全部字符
In [22]: re.search('. # test', 'onefine', re.X).group() Out[22]: 'o' In [23]: re.search('.# test', 'onefine', re.X).group() Out[23]: 'o' In [24]: re.search('. # test', 'onefine', re.X).group() Out[24]: 'o' In [25]: re.search('. # test', 'onefine').group() --------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-25-bffa2d2d5cfc> in <module> ----> 1 re.search('. # test', 'onefine').group() AttributeError: 'NoneType' object has no attribute 'group' In [26]: re.search('. # test', 'o # test haha').group() Out[26]: 'o # test' In [27]:
注:
#
前面的空格都无效#
号 来标识,不过该符号不能在字符串或反斜杠以后。line = "XXX出生于1996年6月" line = "XXX出生于1996/6/1" line = "XXX出生于1996-6-1" line = "XXX出生于1996-06-01" line = "XXX出生于1996-06" regex_str = ".*出生于(\d{4}[年/-]\d{1,2}([月/-]\d{1,2}|[月/-]$|$))"