Python入门之正则表达式
Python 正则表达式
一、简单介绍
正则表达式并不是Python的一部分。正则表达式是用于处理字符串的强大工具,拥有自己独特的语法以及一个独立的处理引擎,效率上可能不如str自带的方法,但功能十分强大。得益于这一点,在提供了正则表达式的语言里,正则表达式的语法都是一样的,区别只在于不同的编程语言实现支持的语法数量不同;但不用担心,不被支持的语法通常是不常用的部分。如果已经在其他语言里使用过正则表达式,只需要简单看一看就可以上手了。
下图展示了使用正则表达式进行匹配的流程: 
二、python中正则表达式的使用
Python通过re模块提供对正则表达式的支持,所有关于正则表达式的操作都使用 python 标准库中的 re 模块。使用re的一般步骤是先将正则表达式的字符串形式编译为Pattern实例,然后使用Pattern实例处理文本并获得匹配结果(一个Match实例),最后使用Match实例获得信息,进行其他的操作。
首先,python中的正则表达式大致分为以下几部分:
- 元字符
- 模式
- 函数
- re内置对象用法
- 分组用法
- 环视用法
1、元字符介绍
- . 匹配任意字符(但不包括换行符)
- ^ 匹配开始位置,多行模式下匹配每一行的开始位置
- $ 匹配结束位置,多行模式下匹配每一行的结束位置
- * 匹配前一个元字符0或无限多次
- + 匹配前一个元字符1或无限多次
- ? 匹配前一个元字符0或一次
- {m} 匹配前一个元字符m次
- {m,n} 匹配前一个元字符m到n次
- {,n} 匹配前一个元字符0至n次;即最多n次
- {m,} 匹配前一个元字符m至无限多次;即最少m次
- \ 转义字符,跟在其后的字符将失去作为特殊元字符的含义。需要转义的特殊字符有* . ? + $ ^ [ ] ( ) { } | \ /;例如\\.只能匹配.,不能再匹配任意字符
- [] 字符集,一个字符集的集合,可以匹配其中任意一个字符
- | 逻辑表达式 或,例如 a|b 代表可匹配 a 或者 b
- (...) 分组,默认为捕获,即被分组的内容可以被单独取出;默认每个分组有个索引,从1开始,按照"("的顺序决定索引值;第一个"("索引为1,其后以此类推
- (?iLmsux) 分组中可以设置模式,iLmsux之中的每一个字符代表一种模式,用法详见 模式介绍
- (?:..) 分组不捕获模式,计算索引时会跳过这个分组
- (?P<name>...) 分组的命名模式,取此分组中的内容时可以使用索引也可以使用name
- (?P=name) 分组的引用模式,可以在同一个正则表达式中引用前面命名过的正则
- (?#...) 注释,不影响正则表达式其他部分
- (?=...) 顺序肯定环视。表示匹配结果所在位置的右侧能够匹配括号内的正则;又称:零宽度正预测先行断言
- (?!...) 顺序否定环视,表示匹配结果所在位置的右侧不能匹配括号内正则;又称:零宽度负预测先行断言
- (?<=...) 逆序肯定环视,表示所在位置左侧能够匹配括号内正则;又称:零宽度正回顾后发断言
- (?<!...) 逆序否定环视,表示所在位置左侧不能匹配括号内正则;又称:零宽度负回顾后发断言
环视用法比较复杂,我暂时也搞不太清楚,大家可以看看下面网址介绍,我觉得比较不错!
环视用法参考:http://www.cnblogs.com/tsql/p/5860889.html
- (?(id/name)yes|no) 若前面指定id或name的分区匹配成功则执行yes处的正则,否则执行no处的正则
参考:https://www.crifan.com/detailed_explanation_about_python_regular_express_yes_or_no_conditional_match/
- \number 匹配和前面索引为number的分组捕获到的内容一样的字符串
- \A 仅匹配字符串开始位置,忽略多行模式
- \Z 仅匹配字符串结束位置,忽略多行模式
- \b 匹配单词边界(包括开始和结束),这里的“单词”,是指连续的字母、数字和下划线组成的字符串。注意,\b的定义是\w和\W的交界
- \B 和\b相反,\B匹配非单词边界
- \d 匹配一个数字,相当于[0-9]
- \D 匹配非数字,相当于[^0-9]
- \s 匹配任意空白字符,相当于[ \t\n\r\f\v];空格( )、水平制表符(\t)、换行符(\n)、回车符(\r)、换页符(\f)、垂直制表符(\v)
- \S 匹配非空白字符,相当于[^ \t\n\r\f\v]
- \w 匹配数字、字母、下划线中的任意一个字符,相当于[a-zA-Z0-9_]
- \W 匹配非数字、字母、下划线中的任意字符,相当于 [^a-zA-Z0-9_]
2、模式介绍
- I IGNORECASE;即忽略大小写匹配模式
#!/usr/bin/env python3 import re s = "Hello Python!" regex = re.compile("hello python!",re.I) #函数中指定模式 print("函数中指定匹配模式:",regex.match(s).group()) regex = re.compile("(?i)hello python!") #正则表达式中直接指定模式 print("正则表达式中指定匹配模式:",regex.match(s).group()) #以上两者指定匹配模式的方式一样的 执行结果: [root@localhost 20170703]# ./re_match.py 函数中指定匹配模式: Hello Python! 正则表达式中指定匹配模式: Hello Python!
- L LOCAL 字符集本地化。这个功能是为了支持多语言版本的字符集使用环境的,比如在转义符/w,在英文环境下,它代表[a-zA-Z0-9],即所以英文字符和数字。如果在一个法语环境下使用,缺省设置下,不能匹配"é" 或 "ç"。加上这L选项和就可以匹配了。不过这个对于中文环境似乎没有什么用,它仍然不能匹配中文字符。
- M MULTILINE,多行模式,改变^和$的位置
#!/usr/bin/env python3 import re s = '''first line1 second line2 third line3''' #^ 正常模式(即单行模式匹配) regex_a = re.compile("^\w+") #匹配以字符、数字或"_"开头的字符 print("匹配开头,单行模式:",regex_a.findall(s)) #^ 多行模式 regex_m = re.compile("^\w+",re.M) #或者regex_m = re.compile("(?m)^\w+") print("匹配开头,多行模式:",regex_m.findall(s)) #$ 正常模式(即单行模式匹配) regex_a = re.compile("\w+$") #匹配以字符、数字或"_"结尾的字符 print("匹配结尾,单行模式:",regex_a.findall(s)) #$ 多行模式 regex_m = re.compile("\w+$",re.M) #或者regex_m = re.compile("(?m)\w+$") print("匹配结尾,多行模式:",regex_m.findall(s)) 执行结果: [root@localhost 20170703]# ./re_match1.py 匹配开头,单行模式: ['first'] 匹配开头,多行模式: ['first', 'second', 'third'] 匹配结尾,单行模式: ['line3'] 匹配结尾,多行模式: ['line1', 'line2', 'line3']
- S DOTALL,此模式下,"."的匹配不受限制,可匹配任何字符,包括换行符
#!/usr/bin/env python3 import re s = '''first line1 second line2 third line3''' #正常模式 regex = re.compile(".+") print("正常模式:",regex.findall(s)) #S或s模式下 regex_dotall = re.compile(".+",re.S) #或regex_dotall = re.compile("(?s).+") print("S或s模式下:",regex_dotall.findall(s)) 执行结果: 正常模式: ['first line1', 'second line2', 'third line3'] S或s模式下: ['first line1\nsecond line2\nthird line3']
- X VERBOSE,冗余模式,此模式忽略正则表达式中的空白和#号的注释
#!/usr/bin/env python3 import re #写一个匹配简单邮箱的正则表达式 email = input("输入注册邮箱!") #regex_email = re.compile("[\w\.]+@[a-zA-Z\d]+\.(com|cn)") #匹配邮箱正则表达式 """ regex_email = re.compile('''[\w\.]+ #匹配@符前的部分 @ #@符 [a-zA-Z\d]+ #邮箱类别 \.(com|cn) #邮箱后缀''',re.X) """ regex_email = re.compile('''(?x)[\w\.]+ #匹配@符前的部分 @ #@符 [a-zA-Z\d]+ #邮箱类别 \.(com|cn) #邮箱后缀''') #以上3中邮箱的正则表达式都一样的! while True: if regex_email.match(email): exit("注册成功!") else: print("邮箱不符合规则!") email = input("再次输入要注册的邮箱!") 执行结果: [root@localhost 20170703]# ./re_match3.py 输入注册邮箱!772632@yy.com 注册成功!
- U UNICODE,使用 \w, \W, \b, \B 这些元字符时将按照 UNICODE 定义的属性.
-
正则表达式的模式是可以同时使用多个的,在 python 里面使用按位或运算符 | 同时添加多个模式
如 re.compile('', re.I|re.M|re.S)
- 其实每个正则表达式的模式,在re模块中其实就是不同的数字
[root@localhost 20170703]# python3 Python 3.6.1 (default, Jun 26 2017, 10:18:59) [GCC 4.8.5 20150623 (Red Hat 4.8.5-11)] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import re >>> re.M <RegexFlag.MULTILINE: 8> >>> re.S <RegexFlag.DOTALL: 16> >>> re.I <RegexFlag.IGNORECASE: 2> >>> re.X <RegexFlag.VERBOSE: 64> >>> re.L <RegexFlag.LOCALE: 4> >>> re.U <RegexFlag.UNICODE: 32>
3、python正则函数介绍
python 的 re 模块提供了很多方便的函数使你可以使用正则表达式来操作字符串,每种函数都有它自己的特性和使用场景,熟悉之后对你的工作会有很大帮助
3.1 compile(pattern,flags=0)
给定一个正则表达式 pattern,指定使用的模式 flags 默认为0 即不使用任何模式;然后会返回一个 SRE_Pattern (参见 第四小节 re 内置对象用法) 对象
#!/usr/bin/env python3 import re regex = re.compile(".+") print(type(regex)) 执行结果: [root@localhost 20170703]# ./re_match4.py <class '_sre.SRE_Pattern'>
这个对象可以调用其他函数来完成匹配,一般来说推荐使用 compile 函数预编译出一个正则模式之后再去使用,这样在后面的代码中可以很方便的复用它,当然大部分函数也可以不用 compile 直接使用
#!/usr/bin/env python3 import re s = '''first line1 second line2 third line3''' regex = re.compile(".+") #compile编译后调用findall函数 print("compile调用findall函数:",regex.findall(s)) #findall直接匹配 print("直接findall直接匹配:",re.findall(".+",s)) 执行结果: [root@localhost 20170704]# ./re_compile.py compile调用findall函数: ['first line1', 'second line2', 'third line3'] 直接findall直接匹配: ['first line1', 'second line2', 'third line3']
3.2 escape(pattern)
转义,如果你需要操作的文本中含有正则的元字符;你在写正则的时候需要将元字符加上反斜扛 \ 去匹配自身, 而当这样的字符很多时,写出来的正则表达式就看起来很乱而且写起来也挺麻烦的,这个时候你可以使用这个函数,用法如下
#!/usr/bin/env python3 import re s = ".+*\d\w123" regex_str = re.escape(".+*\d\w123") print(regex_str) print(type(re.findall(regex_str,s))) print(re.findall(regex_str,s)) for i in re.findall(regex_str,s): print(i) 执行结果: [root@localhost 20170704]# ./re_escape.py \.\+\*\\d\\w123 <class 'list'> ['.+*\\d\\w123'] .+*\d\w123
3.3 findall(pattern,string,flags=0)
参数pattern为正则表达式,string为要匹配的字符串,flags为所用模式,函数作用为在待操作数据中寻找所有匹配正则表达式的字串,返回一个列表,如果没有匹配到任何子串,返回一个空列表。
#!/usr/bin/env python3 import re s = '''first line second line third line''' # compile 预编译后使用 findall;可以匹配到内容 regex_s = re.compile("\w+") print("compile匹配到内容",regex_s.findall(s)) # compile 预编译后使用 findall;没匹配到内容 regex_d = re.compile("\d+") print("compile没匹配到内容",regex_d.findall(s)) # 不使用 compile 直接使用 findall;匹配到内容 print("直接使用findall,匹配到内容",re.findall("\w+", s)) # 不使用 compile 直接使用 findall;没匹配到内容 print("直接使用findall,没匹配到内容",re.findall("\d+", s)) 执行结果: [root@localhost 20170704]# ./re_findall.py compile匹配到内容 ['first', 'line', 'second', 'line', 'third', 'line'] compile没匹配到内容 [] 直接使用findall,匹配到内容 ['first', 'line', 'second', 'line', 'third', 'line'] 直接使用findall,没匹配到内容 []
3.4 finditer(pattern,string,flags=0)
参数和作用与 findall 一样,不同之处在于 findall 返回一个列表, finditer 返回一个迭代器(参见http://www.cnblogs.com/chengd/articles/7096693.html), 而且迭代器每次返回的值并不是字符串,而是一个 SRE_Match (参见 第四小节 re 内置对象用法) 对象,这个对象的具体用法见 match 函数。
#!/usr/bin/env python3 import re s = '''first line second line third line''' # compile 预编译后使用 findall;可以匹配到内容 regex = re.compile("\w+") print("结果类型:",type(regex.finditer(s))) print("finditer结果:",regex.finditer(s)) for i in regex.finditer(s): print("迭代内容:",i) 执行结果: [root@localhost 20170704]# ./re_finditer.py 结果类型: <class 'callable_iterator'> #迭代器类型 finditer结果: <callable_iterator object at 0x7fafe5005278> 迭代内容: <_sre.SRE_Match object; span=(0, 5), match='first'> 迭代内容: <_sre.SRE_Match object; span=(6, 10), match='line'> 迭代内容: <_sre.SRE_Match object; span=(11, 17), match='second'> 迭代内容: <_sre.SRE_Match object; span=(18, 22), match='line'> 迭代内容: <_sre.SRE_Match object; span=(23, 28), match='third'> 迭代内容: <_sre.SRE_Match object; span=(29, 33), match='line'>
3.5 match(pattern,string,flags=0)
使用指定正则去待操作字符串中寻找可以匹配的子串, 返回匹配上的第一个字串,并且不再继续找,需要注意的是 match 函数是从字符串开始处开始查找的,如果开始处不匹配,则不再继续寻找,返回值为 一个 SRE_Match (参见 第四小节 re 内置对象用法) 对象,找不到时返回 None
#!/usr/bin/env python3 import re s = '''first line second line third line''' #可以匹配内容的正则 regex_y = re.compile("\w+") #没匹配到内容的正则 regex_n = re.compile("^i\w+") #为后面操作方面,这里可以将regex.match(s)结果赋值 my = regex_y.match(s) mn = regex_n.match(s) print("匹配到内容类型:") print(my) print(my.group()) print("未匹配到类型内:") print(mn) #print(my.group()) #打印的话会报错,因为没匹配到内容时返回None 执行结果: 匹配到内容类型: <_sre.SRE_Match object; span=(0, 5), match='first'> first 未匹配到类型内: None
3.6 purge()
当你在程序中使用 re 模块,无论是先使用 compile 还是直接使用比如 findall 来使用正则表达式操作文本,re 模块都会将正则表达式先编译一下, 并且会将编译过后的正则表达式放到缓存中,这样下次使用同样的正则表达式的时候就不需要再次编译, 因为编译其实是很费时的,这样可以提升效率,而默认缓存的正则表达式的个数是 100, 当你需要频繁使用少量正则表达式的时候,缓存可以提升效率,而使用的正则表达式过多时,缓存带来的优势就不明显了 (参考 《python re.compile对性能的影响》http://blog.trytofix.com/article/detail/13/), 这个函数的作用是清除缓存中的正则表达式,可能在你需要优化占用内存的时候会用到
3.7 search(pattern,string,flags=0)
函数类似于 match,不同之处在于不限制正则表达式的开始匹配位置
#!/usr/bin/env python3 import re s = '''first line second line third line''' regex = re.compile("i\w+") #match需要从开始出匹配,所以匹配不到 print(regex.match(s)) print("*"*60) #search匹配时。没有限制起始匹配位置 print(regex.search(s)) print(regex.search(s).group()) 执行结果: [root@localhost 20170704]# ./re_search.py None ************************************************************ <_sre.SRE_Match object; span=(1, 5), match='irst'> irst
3.8 split(pattern, string, maxsplit=0, flags=0)
参数 maxsplit 指定切分次数, 函数使用给定正则表达式寻找切分字符串位置,返回包含切分后子串的列表,如果匹配不到,则返回包含原字符串的一个列表
#!/usr/bin/env python3 import re s = '''first 1 line second 2 line third 3 line''' regex_n = re.compile("\d+") regex_d = re.compile("""\.+ #.被转义""",re.X) #指定.分分割符 #匹配到指定字符,返回分割收后的字符串列表 print(regex_n.split(s)) #匹配不到字符,返回自身的列表 print(regex_d.split(s)) #指定分割次数,默认不指定则分割到最后 print(regex_n.split(s,2)) 执行结果: ['first ', ' line\nsecond ', ' line\nthird ', ' line'] #默认分割所有匹配到的字符,并返回列表 ['first 1 line\nsecond 2 line\nthird 3 line'] #没有匹配内容,则返回以自身为元素的列表 ['first ', ' line\nsecond ', ' line\nthird 3 line'] #分割了2次
3.9 sub(pattern, repl, string, count=0, flags=0)
替换函数,将正则表达式 pattern 匹配到的字符串替换为 repl 指定的字符串, string是要被匹配的字符串,参数 count 用于指定最大替换次数
cat re_sub.py #!/usr/bin/env python3 import re s = "the sum of 7 and 9 is [7+9]." #基本用法,将目标替换为固定字符串 print("基本用法,替换为固定字符串:",re.sub("\[7\+9\]","16",s)) #高级用法1:使用分组捕获内容,\1代表pattern捕获的第一个分组内容,以此类推 print("替换分组捕获内容:",re.sub('\[(7)\+(9)\]',r'\2\1',s)) #r'\2\1'原生字符,表示不做转义,\2表示索引2捕获内容即(9),\1表示索引1捕获内容即(7) #高级用法2:使用函数型repl参数,处理匹配得到的SRE_Match 对象 def repl(m): p_str = m.group() #参见"re 内置对象用法" #print(p_str) if p_str == '7': return '77' if p_str == '9': return '99' return '' print("函数型参数普通替换:",re.sub('\d', repl, s)) ''' 解析: 1、先通过正则表达式匹配数据,得到SRE_Match对象 2、将得到的SRE_Match对象当做参数传入替换repl函数 3、判断匹配到的字符串,将符合条件的通过return返回并替换 '''
# 高级用法 3 使用函数型 repl 参数, 处理匹配到的 SRE_Match 对象 增加作用域 自动计算
scope = {} example_string_1 = "the sum of 7 and 9 is [7+9]." example_string_2 = "[name = 'Mr.Gumby']Hello,[name]" def replacement(m): code = m.group(1) st = '' try: st = str(eval(code, scope)) except SyntaxError: exec(code,scope) return st # 解析: code='7+9' # str(eval(code, scope))='16' print(re.sub('\[(.+?)\]', replacement, example_string_1)) # output> the sum of 7 and 9 is 16. # 两次替换 # 解析1: code="name = 'Mr.Gumby'" # eval(code) # raise SyntaxError # exec(code in scope) # 在命名空间 scope 中将 "Mr.Gumby" 赋给了变量 name # 解析2: code="name" # eval(name) 返回变量 name 的值 Mr.Gumby print(re.sub('\[(.+?)\]', replacement, example_string_2)) # output> Hello,Mr.Gumby 执行结果: [root@localhost 20170706]# ./re_sub.py 基本用法,替换为固定字符串: the sum of 7 and 9 is 16. 替换分组捕获内容: the sum of 7 and 9 is 97. 函数型参数普通替换: the sum of 77 and 99 is [77+99]. the sum of 7 and 9 is 16. Hello,Mr.Gumby
3.10 subn(pattern, repl, string, count=0, flags=0)
作用与函数 sub 一样, 唯一不同之处在于返回值为一个元组,第一个值为替换后的字符串,第二个值为发生替换的次数
#!/usr/bin/env python3 import re s = "the sum of 7 and 9 is [7+9]." #将目标替换为固定字符串,并将替换后的字符串及替换次数以元组形式返回 print("基本用法,替换为固定字符串:",re.subn("\[7\+9\]","16",s)) 执行结果: [root@localhost 20170707]# ./re_subn.py 基本用法,替换为固定字符串: ('the sum of 7 and 9 is 16.', 1)
4、re内置对象用法
4.1 SRE_Pattern 这个对象是一个编译后的正则表达式,编译后不仅能够复用和提升效率,同时也能够获得一些其他的关于正则表达式的信息
属性:
flags:编译时指定的模式
groupindex:以正则表达式中别名组的别名为键、对应编号为值的字典,没有别名的组不包含在内。
groups:正则表达中分组的数量
pattern:编译时用的正则表达式
python3中re模式返回的数字和python2是不同的;具体什么原因我暂时还不知道,有知道的朋友可以告知下,非常感谢!
#python3 #!/usr/bin/env python3 import re s = 'Hello, Mr.Gumby : 2016/10/26' p = re.compile('''(?: # 构造一个不捕获分组 用于使用 | (?P<name>\w+\.\w+) # 匹配 Mr.Gumby | # 或 (?P<no>\s+\.\w+) # 一个匹配不到的命名分组 ) .*? # 匹配 : (\d+) # 匹配 2016 ''',re.X) print(p.flags) print(p.groupindex) print(p.groups) print(p.pattern) 执行结果: [root@localhost 20170707]# ./re_sre3.py 96 #python3中re.X返回的是96 {'name': 1, 'no': 2} #name第一个捕获分组,no是第二个捕获分组 3 #正则中总共3个捕获分组 #以下是编译时用的正则表达式 (?: # 构造一个不捕获分组 用于使用 | (?P<name>\w+\.\w+) # 匹配 Mr.Gumby | # 或 (?P<no>\s+\.\w+) # 一个匹配不到的命名分组 ) .*? # 匹配 : (\d+) # 匹配 2016
下面是python2 下执行
#!/usr/bin/python # encoding: utf-8 import re s = 'Hello, Mr.Gumby : 2016/10/26' p = re.compile('''(?: # 构造一个不捕获分组 用于使用 | (?P<name>\w+\.\w+) # 匹配 Mr.Gumby | # 或 (?P<no>\s+\.\w+) # 一个匹配不到的命名分组 ) .*? # 匹配 : (\d+) # 匹配 2016 ''',re.X) print p.flags print p.groupindex print p.groups print p.pattern 执行结果:
[root@localhost 20170707]# ./re_sre2.py 64 #python2中re.X返回的值是64 {'name': 1, 'no': 2} 3 (?: # 构造一个不捕获分组 用于使用 | (?P<name>\w+\.\w+) # 匹配 Mr.Gumby | # 或 (?P<no>\s+\.\w+) # 一个匹配不到的命名分组 ) .*? # 匹配 : (\d+) # 匹配 2016
正则编译函数:可被使用 findall、finditer、match、search、split、sub、subn 等函数(详见各函数使用方法)
4.2 SRE_Match 这个对象会保存本次匹配的结果,包含很多关于匹配过程以及匹配结果的信息
属性:
endpos:本次搜索结束位置索引
lastgroup:本次搜索匹配到的最后一个分组的别名
lastindex:本次搜索匹配到的最后一个分组的索引
pos:本次搜索开始位置的索引
re:本次搜索使用的SRE_Pattern对象
regs:返回元组,元素为元组;包含本次搜索匹配到的所有分组的起止位置
string:本次搜索操作的字符串
#!/usr/bin/python3 import re s = 'Hello, Mr.Gumby : 2016/10/26' m = re.search(', (?P<name>\w+\.\w+).*?(\d+)', s) # 本次搜索的结束位置索引 print(m.endpos) # 本次搜索匹配到的最后一个分组的别名 # 本次匹配最后一个分组没有别名;若最后一个分组没有命名分组,则返回None print(m.lastgroup) # 本次搜索匹配到的最后一个分组的索引; print(m.lastindex) # 本次搜索开始位置索引 print(m.pos) # 本次搜索使用的 SRE_Pattern 对象 print(m.re)
print(type(m.re)) # 元组,元素为元组,包含本次搜索匹配到的所有分组的起止位置 第一个元组为正则表达式匹配范围 print(m.regs) print(type(m.regs)) # 本次搜索操作的字符串 print(m.string) 执行结果: [root@localhost 20170707]# ./re_Match3.py 28 #搜索结束索引位置 None #会后一个分组不是命名分组,返回None 2 #最后一个分组索引 0 #搜索开始索引位置 re.compile(', (?P<name>\\w+\\.\\w+).*?(\\d+)') #本次搜索使用的编译后的正则表达式,即SRE_Pattern
((5, 22), (7, 15), (18, 22)) #返回所有匹配分组的起止位置;第一个元素为正则表达式匹配范围 <class 'tuple'> #regs类型 Hello, Mr.Gumby : 2016/10/26 #本次搜索操作的字符串
函数:
end([group=0]):返回指定分组的结束位置,默认返回正则表达式所匹配到的最后一个字符的索引
expand(template):根据模版返回相应的字符串,类似与 sub 函数里面的 repl, 可使用 \1 或者 \g<name> 来选择分组
group([group1, ...]):根据提供的索引或名字返回响应分组的内容,默认返回 start() 到 end() 之间的字符串, 提供多个参数将返回一个元组
groupdict([default=None]):返回一个包含所有匹配到的命名分组的字典,没有命名的分组不包含在内,key 为组名, value 为匹配到的内容,参数default 为没有参与本次匹配的命名分组提供默认值
groups([default=None]):以元组形式返回每一个分组匹配到的字符串,包括没有参与匹配的分组,其值为 default
span([group]):返回指定分组的起止位置组成的元组,默认返回由 start() 和 end() 组成的元组
start([group]):返回指定分组的开始位置,默认返回正则表达式所匹配到的第一个字符的索引
#!/usr/bin/env python3 import re s = 'Hello, Mr.Gumby : 2016/10/26' m = re.search('''(?: # 构造一个不捕获分组 用于使用 | (?P<name>\w+\.\w+) # 匹配 Mr.Gumby | # 或 (?P<no>\s+\.\w+) # 一个匹配不到的命名分组 ) .*? # 匹配 : (\d+) # 匹配 2016 ''', s, re.X) # 返回指定分组的结束位置,默认返回正则表达式所匹配到的最后一个字符的索引 print(m.end()) print("*"*60) # 根据模版返回相应的字符串,类似与 sub 函数里面的 repl, 可使用 \1 或者 \g<name> 来选择分组 print(m.expand(r"my name is \1")) print(m.expand(r"my name is \g<name>")) print("*"*60) # 根据提供的索引或名字返回响应分组的内容,默认返回 start() 到 end() 之间的字符串, 提供多个参数将返回一个元组 print(m.group()) print(m.group(1,2)) print("*"*60) # 返回 返回一个包含所有匹配到的命名分组的字典,没有命名的分组不包含在内,key 为组名, value 为匹配到的内容,参数 default 为没有参与本次匹配(即没匹配到的)的命名分组提供默认值 print(m.groupdict('default_string')) print("*"*60) # 以元组形式返回每一个分组匹配到的字符串,包括没有参与匹配的分组,其值为 default print(m.groups('default_string')) print("*"*60) # 返回指定分组的起止未知组成的元组,默认返回由 start() 和 end() 组成的元组 print(m.span(3)) print("*"*60) # 返回指定分组的开始位置,默认返回正则表达式所匹配到的第一个字符的索引 print(m.start(3)) 执行结果: [root@localhost 20170707]# ./re_Match_func3.py 22 ************************************************************ my name is Mr.Gumby my name is Mr.Gumby ************************************************************ Mr.Gumby : 2016 ('Mr.Gumby', None) ************************************************************ {'name': 'Mr.Gumby', 'no': 'default_string'} ************************************************************ ('Mr.Gumby', 'default_string', '2016') ************************************************************ (18, 22) ************************************************************ 18
参考:http://www.cnblogs.com/dyfblog/p/5880728.html
***********************************************************
学习永远不晚。——高尔基
***********************************************************

浙公网安备 33010602011771号