Python入门之正则表达式

Python 正则表达式

一、简单介绍

正则表达式并不是Python的一部分。正则表达式是用于处理字符串的强大工具,拥有自己独特的语法以及一个独立的处理引擎,效率上可能不如str自带的方法,但功能十分强大。得益于这一点,在提供了正则表达式的语言里,正则表达式的语法都是一样的,区别只在于不同的编程语言实现支持的语法数量不同;但不用担心,不被支持的语法通常是不常用的部分。如果已经在其他语言里使用过正则表达式,只需要简单看一看就可以上手了。

下图展示了使用正则表达式进行匹配的流程: 

二、python中正则表达式的使用

Python通过re模块提供对正则表达式的支持,所有关于正则表达式的操作都使用 python 标准库中的 re 模块。使用re的一般步骤是先将正则表达式的字符串形式编译为Pattern实例,然后使用Pattern实例处理文本并获得匹配结果(一个Match实例),最后使用Match实例获得信息,进行其他的操作。

 首先,python中的正则表达式大致分为以下几部分:

  1. 元字符
  2. 模式
  3. 函数
  4. re内置对象用法
  5. 分组用法
  6. 环视用法

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

 

***********************************************************

 学习永远不晚。——高尔基

***********************************************************

posted @ 2017-07-08 11:58  chengd  阅读(552)  评论(0)    收藏  举报