精华内容
下载资源
问答
  • 今天小编就为大家分享一篇Python 正则表达式 re.match/re.search/re.sub的使用解析,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
  • 分组小括号() 有直接...re.match()方法: 只匹配字符串开始的位置 有名分组: 给分组取名?P,可以用名字取匹配的结果 re.compile() 编译正则表达式,提高效率 以上就是软件开发网小编整理的相关知识点内容,感谢大家
  • Python高级——正则表达式 re模块1.match方法

    万次阅读 多人点赞 2017-11-03 12:04:06
    python正则表达式 一、什么是正则表达式 正则表达式也叫做匹配模式(Pattern),它由一组具有特定含义的字符串组成,通常用于匹配和替换文本。 正则表达式,是一个独立的技术,很多编程语言支持正则表达式处理。 ...

     
    python:正则表达式

    一、什么是正则表达式

    正则表达式也叫做匹配模式(Pattern),它由一组具有特定含义的字符串组成,通常用于匹配和替换文本

    正则表达式,是一个独立的技术,很多编程语言支持正则表达式处理。

    Wiki:正则表达式(英语:Regular Expression、regex或regexp,缩写为RE),也译为正规表示法、常规表示法,在计算机科学中,是指一个用来描述或者匹配一系列符合某个句法规则字符串的单个字符串。在很多文本编辑器或其他工具里,正则表达式通常被用来检索和/或替换那些符合某个模式的文本内容。许多程序设计语言都支持利用正则表达式进行字符串操作。正则表达式通常缩写成“regex”,单数有regexp、regex,复数有regexps、regexes、regexen。

    通常情况下,如果一个文本中出现了多个匹配,正则表达式返回第一个匹配,如果将 global 设置为 true,则会返回全部匹配;匹配模式是大小写敏感的,如果设置了 ignore case 为 true,则将忽略大小写区别。

    有时侯正则表达式也简称为表达式、匹配模式或者模式,它们可以互换。 这里默认 global 和 ignore case 均为 true。

    为什么要使用正则表达式

    在软件开发过程中,经常会涉及到大量的关键字等各种字符串的操作,使用正则表达式能很大程度的简化开发的复杂度和开发的效率,所以在Python中正则表达式在字符串的查询匹配操作中占据很重要的地位

    二、Python中的re模块

    1.Python为了方便大家对于正则的使用,专门为大家提供了re模块供我们使用。

    import re  # 导入re模块

    dir(re)  # 查看re模块的方法和属性

    ['A', 'ASCII', 'DEBUG', 'DOTALL', 'I', 'IGNORECASE', 'L', 'LOCALE', 'M', 'MULTILINE', 'RegexFlag', '

    S', 'Scanner', 'T', 'TEMPLATE', 'U', 'UNICODE', 'VERBOSE', 'X', '_MAXCACHE', '__all__', '__builtins_

    _', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '__ver

    sion__', '_alphanum_bytes', '_alphanum_str', '_cache', '_compile', '_compile_repl', '_expand', '_loc

    ale', '_pattern_type', '_pickle', '_subx', 'compile', 'copyreg', 'enum', 'error', 'escape', 'findall

    ', 'finditer', 'fullmatch', 'functools', 'match', 'purge', 'search''split', 'sre_compile', 'sre_pa

    rse', 'sub', 'subn', 'template']

    查看字符串是否是以“lili”开头

    import re  # 导入re模块

    str = "lili" # 定义一个字符串等于lili

    #  查看"lili  is  a good girl"是否lili开头,结果保存到res中

    res = re.match(str,"mayun is very good shangren") 

    # 使用res.group()提取匹配结果,如果是,则返回匹配对象(Match Object),否则返回None,

    res.group()  # 将匹配的结果显示

    结果如下:

      ‘lili'


    请看在命令行运行的例子:


    注意:re.match( )方法匹配的是以xxx开头的字符串,若不是开头的,尽管属于str内,则无法匹配。


    2.元字符

    我们发现,虽然Python为外面提供了re模块供我们使用,但是功能太弱,远远无法满足我们的使用,所以我们需要继续学习正则的其他知识。

    首先我们来看看正则的单个字符的匹配是如何完成的。

    表1.常用的元字符

    代码

    说明

    .

    匹配除换行符(\n)以外的任意字符

    \w

    匹配字母或数字或下划线或汉字0-9、a-z、A-Z、_(下划线)、汉字和其他国家的语言符号

    \W

    匹配非字母或数字或下划线或汉字,跟\w正好相反

    \s

    匹配任意的空白符

    \S

    匹配任意非空白符

    \d

    匹配数字

    \D

    匹配非数字

    \b

    匹配单词的开始或结束

    ^

    匹配字符串的开始

    $

    匹配字符串的结束

    []

    匹配[]中列举的字符

    实例如下:

    re.match(".","A")                                                                                   运行结果:<_sre.SRE_Match object; span=(0, 1), match='A'>

    re.match(".","8")                                                                                   运行结果: <_sre.SRE_Match object; span=(0, 1), match='8'>

    re.match(".","_")                                                                                    运行结果:<_sre.SRE_Match object; span=(0, 1), match='_'>

    re.match(".","liushuaige")                                                                     运行结果:<_sre.SRE_Match object; span=(0, 1), match='l'>

    re.match(".","10086") #注意,只匹配第一个字符                                    运行结果:<_sre.SRE_Match object; span=(0, 1), match='1'>

    re.match(".*","10086”)  # *表示匹配0到多个字符                                  运行结果:<_sre.SRE_Match object; span=(0, 5), match='10086'>

    re.match(".","\n10086") 注意,在正则中\n(换行键是无法匹配的)         运行结果:无

    re.match(".","\t10086") #注意,\t为制表符,相当于一个字符                  运行结果:<_sre.SRE_Match object; span=(0, 1), match='\t'>

    re.match(".....","10086")                                                                          运行结果:<_sre.SRE_Match object; span=(0, 5), match='10086'>

    re.match(".*\\bgood\\b.*","today is a good day")                                 运行结果:<_sre.SRE_Match object; span=(0, 19), match='today is a good day'>

    re.match(".*(\\bgood\\b).*","today is a good day").group(1)                运行结果:'good'


    # 匹配数字

    re.match("[123456789]"," 6这个真是一个悲伤的故事 ")                         运行结果:<_sre.SRE_Match object; span=(0, 1), match='6'>

    re.match("[0-9]"," 6这个真是一个悲伤的故事 ")                                    运行结果:<_sre.SRE_Match object; span=(0, 1), match='6'>

    re.match("[a-z]","this is good day")                                                     运行结果:<_sre.SRE_Match object; span=(0, 1), match='t'>

    re.match("[a-z0-9A-Z]"," this is good day")                                         运行结果: <_sre.SRE_Match object; span=(0, 1), match='t'>                               

    re.match("[a-z0-9A-Z王小明]","小this is good day")                            运行结果: <_sre.SRE_Match object; span=(0, 1), match='小'>   

    # 匹配所有中文

    re.match("[\u4e00-\u9fa5]","大幅的发生")     #汉字                              运行结果:  <_sre.SRE_Match object; span=(0, 1), match='大'>                     

    re.match("我今年5岁了","我今年5岁了")                                                 运行结果:<_sre.SRE_Match object; span=(0, 6), match='我今年5岁了'>

    re.match("我今年\d岁了","我今年55岁了") # error 因为\d只会匹配一个数字          运行结果:无

    re.match("我今年\d岁了","我今年55岁了")                                                       运行结果:无                               

    re.match("\D","我今年55岁了")             #数字                                                  运行结果:<_sre.SRE_Match object; span=(0, 1), match='我'>

    re.match("\D*","我今年55岁了")              # 非数字                                           运行结果:<_sre.SRE_Match object; span=(0, 3), match='我今年'>

    re.match("\s","    我今年55岁了")          # 空白符                                              运行结果:<_sre.SRE_Match object; span=(0, 1), match=' '>

    re.match("\s","\t我今年55岁了")                                                                       运行结果:<_sre.SRE_Match object; span=(0, 1), match='\t'>

    re.match("\s","\n我今年55岁了")        #注意*不能匹配\n(换行符)                  运行结果:<_sre.SRE_Match object; span=(0, 1), match='\n'>

    re.match("\s","\r我今年55岁了")                                                                       运行结果:<_sre.SRE_Match object; span=(0, 1), match='\r'>

    3.字符转义

    如果你想查找元字符本身的话,比如你查找.,或者*,就出现了问题:你没法指定它们,因为它们会被解释成其它的意思。这时你就必须使用\来取消这些字符的特殊意义。因此,你应该使用\.和\*。当然,要查找\本身,你也得用\\.

    如:c:\\d\\e\\f.txt

    re.match("c:\\","c:\\a\\b") # error 报错,因为\\转义后就变成了\了

    re.match("c:\\\\","c:\\a\\b") #正确

    re.match(r"c:\\","c:\\a\\b") # 正确,在前面加“r”表示匹配的字符不进行转义,以后匹配符不要再写出上面的的转义了。

    4.重复

    在字符串的匹配中,不可避免的会出现重复字符,我们如何进行很友好的匹配呢?

    表2.常用的限定符

    代码/语法

    说明

    *

    重复零次或更多次

    +

    重复一次或更多次

    ?

    重复零次或一次

    n}

    重复n次

    {n,}

    重复n次或更多次

    {n,m}

    重复n到m次

    下面是一些使用重复的例子:

    Windows\d+匹配Windows后面跟1个或更多数字

    1[238]\d{9}匹配以13后面跟9个数字(中国的手机号)

    ^\w+匹配一行的第一个单词(或整个字符串的第一个单词,具体匹配哪个意思得看选项设置)

    +和*的差别

    re.match("a[0-9]+h$","ah")                        运行结果:无

    re.match("a[0-9]*h$","ah")                          运行结果:<_sre.SRE_Match object; span=(0, 2), match='ah'>


    re.match("[A-Z][a-z]*","Liujianhong ")                                                         运行结果:<_sre.SRE_Match object; span=(0, 11), match='Liujianhong'>

    re.match("[A-Za-z]*","LiuJianhong ")                                                           运行结果:<_sre.SRE_Match object; span=(0, 11), match='LiuJianhong'>

    re.match("[A-Z][a-z]*","LiuJianhong ")                                                         运行结果:<_sre.SRE_Match object; span=(0, 3), match='Liu'>(因为J是大写的)

    re.match("[a-zA-Z_]+[\w_]*","LiuJianhong3 ")                                             运行结果:<_sre.SRE_Match object; span=(0, 12), match='LiuJianhong3'>

    re.match("[0-9]?[\d]","1")                                                                             运行结果:<_sre.SRE_Match object; span=(0, 1), match='1'>

    re.match("[0-9]?[\d]","111")                                                                         运行结果:<_sre.SRE_Match object; span=(0, 2), match='11'>

    re.match("a[0-9]?h$","a12456h")                                                                 运行结果:无

    re.match("a[0-9]?h$","ah")                                                                           运行结果:<_sre.SRE_Match object; span=(0, 2), match='ah'>

    re.match("a[0-9]?h$","a3h")                                                                         运行结果:<_sre.SRE_Match object; span=(0, 3), match='a3h'>

    re.match("\w{5}","1sadfasdf11")                                                                  运行结果:<_sre.SRE_Match object; span=(0, 5), match='1sadf'>

    re.match("\w{5,}","1sadfasdf11")                                                                 运行结果:<_sre.SRE_Match object; span=(0, 11), match='1sadfasdf11'>

    re.match("\w{5,9}","1sadfasdf11")                                                               运行结果:<_sre.SRE_Match object; span=(0, 9), match='1sadfasdf'>

    re.match(".*\\bliu\\b","i is liu fas fsa5 662 2a") # 注意为什么使用点            运行结果:<_sre.SRE_Match object; span=(0, 8), match='i is liu'>

    re.match(r".*\bliu\b","i is liu fas fsa5 662 2a")  #结果同上                           运行结果:<_sre.SRE_Match object; span=(0, 8), match='i is liu'>

    练习:匹配出qikux的邮箱地址,且@之前有4到20为字符,如59127_ljh@qikux.com

    \w{4,20}@qikux\.com



    以上是对“*”,“+”,“?”的举例,将这三种符号添加至某要求后,说明可重复0到多次,或者1到多次,或者0或者1次。重复的字符为在“*”,“+”,“?”之前的如“\d”

    5.反义

    有时需要查找不属于某个能简单定义的字符类的字符。比如想查找除了数字以外,其它任意字符都行的情况,这时需要用到反义:

    表3.常用的反义代码

    代码/语法

    说明

    \W

    匹配任意不是字母,数字,下划线,汉字的字符

    \S

    匹配任意不是空白符的字符

    \D

    匹配任意非数字的字符

    \B

    匹配不是单词开头或结束的位置

    [^x]

    匹配除了x以外的任意字符

    [^aeiou]

    匹配除了aeiou这几个字母以外的任意字符

    案例如下:

    re.match("[^abcd]","a")  #表示除a、b、c、d外的任何字符都匹配

    re.match("[^abcd]","b")

    re.match("[^abcd]","e")

    6.分组

    我们已经提到了怎么重复单个字符(直接在字符后面加上限定符就行了);但如果想要重复一个字符串又该怎么办?你可以用小括号来指定子表达式(也叫做分组),然后你就可以指定这个子表达式的重复次数了,你也可以对子表达式进行其它一些操作。

    案例如下:

    re.match("100|[1-9][0-9]|[0-9]","2") # 匹配100以内的数

    re.match("0|100|[1-9]?\d$","2") 

    re.match("\d+(183|192|168)\s","452183 ")

    re.match("\d+(183|192|168)\s","452183 ").group()

    re.match("\d+(183|192|168)\s","452183 ").group(1) #注意当输入1的结果

    re.match("\d+(183|192|168)\.(li|wang|liu)","452168.wang").group(2) 

    re.match("(.*)-(\d+)","0931-5912872 ").group(2) #小括号的使用场景特别方便

    re.match("<[a-zA-Z]*>\w*</[a-zA-Z]*>","<a>liujianhong</a>") #看似正确,其实Error

    re.match("<[a-zA-Z]*>\w*</[a-zA-Z]*>","<a>liujianhong</html>") #这个就是漏洞

    re.match(r"<([a-zA-Z] *)>\w*</ \1>","<a>liujianhong</html>") #此时\1表示第一个括号中的值

    re.match("<([a-zA-Z] *)>\w*</ \\1>","<a>liujianhong</html>") #这样也

    分组:即用圆括号将要提取的数据包住,通过 .group()获取,一般和“|”结合使用,可以用以下实例来讲述分组的应用场景:





    7.后向引用(了解)

    后向引用用于重复搜索前面某个分组匹配的文本。例如,\1代表分组1匹配的文本。最好还是拿例子来说明吧:

    re.match(r"<(\w*)><(\w*)>.*</\2></\1>","<a><span>liujianhong</span></a>")

    re.match(r"<(?P<n1>\w*)><(?P<n2>\w*)>.*</(?P=n2)></(?P=n1)>","<a><span>liujiang</span></a>")

    注意?P<name> ?P=name的P必须大写。

    展开全文
  • python re.search 和 re.match 正则表达式

    千次阅读 2015-09-29 10:49:47
    python提供了2中主要的正则表达式操作:re.matchre.search。 match :只从字符串的开始与正则表达式匹配,匹配成功返回matchobject,否则返回none; search :将字符串的所有字串尝试与正则表达式
    原文:http://www.111cn.net/phper/157/37171_1.htm
    

    一 re.search 和 re.match

    python提供了2中主要的正则表达式操作:re.match 和 re.search。

    match :只从字符串的开始与正则表达式匹配,匹配成功返回matchobject,否则返回none;
    search :将字符串的所有字串尝试与正则表达式匹配,如果所有的字串都没有匹配成功,返回none,否则返回matchobject;(re.search相当于perl中的默认行为)

     

    实例代码:

    import re

    def testsearchandmatch():
      s1="helloworld, i am 30 !"
      
      w1 = "world"
      m1 =  re.search(w1, s1)
      if m1:
        print("find : %s" % m1.group())
        
      if re.match(w1, s1) == none:
        print("cannot match")
        
      w2 = "helloworld"
      m2 = re.match(w2, s1)
      if m2:
        print("match : %s" % m2.group())

    testsearchandmatch()
    #find : world
    #cannot match
    #match : helloworld
     

    二 re.compile 和 re.ignorecase

    re.compile返回regrexobject对象, 用来重复使用regrexobject;

    re.ignorecase用来在匹配时忽略大小写;

     

    实例代码:

    def testcompile():
      regex = "d{3}-d{7}"
      
      regexobject = re.compile(regex)
      print(regexobject.search("aaa 027-4567892").group())
      print(regexobject.search("bbb 021-1234567").group())
      print(regexobject.search("ccc 010-123456"))

    testcompile()
    #027-4567892
    #021-1234567
    #none

    def testignorecase():
      print(re.search('world', "hello world !").group())
      print(re.search('world', "hello world !", re.ignorecase).group())
      print(re.search('world', "hello world !"))
      
    testignorecase()
    #world
    #world
    #none

    三 matchobject

    matchobject为re.search,re.match等匹配成功后返回的对象,包含了匹配的结果。

    在正则表达式中,可以使用()来将部分正则表达式分组且编号,编号从1开始,使用数字来使用,例如1 2 3,(?p<name>)还可以给分组命名, 使用(?p=name)来使用命名的组。

    matchobject.group()包含了所有匹配的内容,等价于matchobject.group(0),此时的0表示所有的匹配;

    matchobject.groups教程()包含了正则表达式中所有使用()定义的组对应的匹配内容;

    matchobject.group(n),表示返回正则表达式中的第n个组()匹配的内容,此时n不为0, 等价于matchobject.groups()[n-1];

    matchobject.lastindex, 表示正则表达式中分组()的个数;

     实例代码:

    def testmatchobject():
      m = re.match(r"(?p<year>d{4})-(?p<month>d{2})-(?p<date>d{2})", "2010-10-01, i am very happy")
      print(m.group())
      print(m.group(0))
      
      print(m.groups())
      
      print(m.group(1))  
      print(m.groups()[0])
      
      print(m.group(2))  
      print(m.groups()[1])
      
      print(m.group(3))  
      print(m.groups()[2])
      
      print(m.groupdict())
      
      print(m.lastindex)

    testmatchobject()
    #2010-10-01
    #2010-10-01
    #('2010', '10', '01')
    #2010
    #2010
    #10
    #10
    #01
    #01
    #{'date': '01', 'year': '2010', 'month': '10'}
    #3
     

     

    四 re和matchobject的方法split+findall+finditer+sub

    split方法,使用给定的表达式来分割字符串;

    findall方法,返回所有的与给定的表达式匹配的一个list;

    finditer方法,返回所有与给定的表达式匹配的matchobject的iterator;

    sub方法,使用新的字符串替换表达式匹配的字符串;

    实例代码:

    def testreandmatchobjectmethonds():
      #split findall finditer sub  
      s1 = "i am working in microsoft !"
      l = re.split('s+', s1) # l is list type
      print( l)
      
      s2 = "aa 12 bb 3 cc 45 dd 88 gg 89"
      l2 = re.findall('d+', s2)
      print(l2)
      
      it = re.finditer('d+', s2) # it is one iterator type
      for i in it: # i is matchobject type
        print (i.group())
        
      s3 = re.sub('d+', '200', s2)
      print(s3)
      
    testreandmatchobjectmethonds()
    #['i', 'am', 'working', 'in', 'microsoft', '!']
    #['12', '3', '45', '88', '89']
    #12
    #3
    #45
    #88
    #89
    #aa 200 bb 200 cc 200 dd 200 gg 200

     

    五 re.search只返回第一个匹配

     

    实例代码:

    def testsearch():
      s1 = "bb 3 cc 45 dd 88 gg 89"
      m = re.search('d+', s1)
      print(m.group())

    testsearch()
    #3



    展开全文
  • .re 匹配时使用的pattern对象(正则表达式) .pos 正则表达式搜索文本的开始位置 .endpos 正则表达式搜索文本的结束位置 Match对象常用方法 方法 说明 .group(0) 获得匹配后的字符串 .start() 匹配...

    Match对象的常用属性

    属性说明
    .string待匹配 的文本
    .re匹配时使用的pattern对象(正则表达式)
    .pos正则表达式搜索文本的开始位置
    .endpos正则表达式搜索文本的结束位置

    Match对象常用方法

    方法说明
    .group(0)获得匹配后的字符串
    .start()匹配字符串在原始字符串的开始位置
    .end()匹配字符串在原始字符串的结束位置
    .span()返回(.start(),.end())

    Match对象属性及方法使用实例

    
    >>> import re
    >>> m=re.search(r'[1-9]\d{5}','BIT100081 TSU100084')
    >>> m.string
    

    得到带匹配的文本
    ‘BIT100081 TSU100084’

    >>> m.re
    
    

    得到匹配时的pattern对象
    re.compile(’[1-9]\d{5}’)

    
    >>> m.pos
    

    得到正则表达式文本的开始位置
    0

    
    >>> m.endpos
    

    与上面对应的文本的结束位置
    19

    
    >>> m.group(0)
    

    得到匹配后的字符串的第一个
    ‘100081’

    
    >>> m.start()
    

    得到匹配的字符串在原始字符串’BIT100081 TSU100084’中开始的位置
    3

    
    >>> m.end()
    

    与上对应的得到匹配的字符串在原始字符串’BIT100081 TSU100084’的结束位置
    9

    
    >>> m.span()
    

    返回(.start(),.end())
    (3, 9)

    展开全文
  • Python re模块 (正则表达式用法剖析详解)

    千次阅读 多人点赞 2019-10-23 20:18:51
    Python re模块不等于正则表达式!文章整理了re模块的用法,收集整理了正则表达式的内容,详细的解读了正则表达式的用法,例举了re模块如何使用到正则表达式!

    正则表达式

    字符组

    字符组 : [字符组]
    在同一个位置可能出现的各种字符组成了一个字符组,在正则表达式中用“ [ ] ”表示
    字符分为很多类,比如数字、字母、标点等等。
    假如要求一个位置"只能出现一个数字",那么这个位置上的字符只能是0、1、2...9这10个数之一
    

    在这里插入图片描述


    字符(元字符)

    在这里插入图片描述

    \w 包括:字母、数字、下划线;如果验证要求只允许输入:“数字和字母” 不能单独 \w 解决,
    还要考虑到下划线,所以只能写成[0-9a-zA-Z] 
    
    import re
    
    strd = input("please:")
    if re.search("^[0-9a-zA-Z]+$", strd):
    
        print("输入正确")
    else:
        print("错误")
    

    在这里插入图片描述

    # [/s/S] 、[/d/D]、[/w/W] 这类的可以匹配任意字符
    

    量词(个数)

    在这里插入图片描述
    在这里插入图片描述

    边界字符(也属于元字符)

    在这里插入图片描述

     有一些有特殊意义的元字符进入字符组中会回复它本来的意义如: . | [ ] ( )
    ^ 匹配字符串的开始 如: ^x ,表示字符串必须以x开头, 注意:[^ ] 意义不同
    $ 匹配字符串的结束 如: x$ , 表示字符串必须以x结尾
    
    ^,$ : 如果字符有多行, 且在 re.M 模式下, ^,$ 会将每一行当作一个字符串,
    	即换行后会重新匹配
    
    \A 匹配字符串的开始,^ 类似,: \Ax ,表示字符串必须以x开头
    \Z 匹配字符串的结尾, 与$类似,: x\Z,表示字符串必须以x结尾
    # \A ,\Z , 在re.M模式下不会影响多行匹配
    
    \b 用来匹配单词的结尾,: er\b 表示单词是否以 er结束
    \B 用来匹配非单词的结尾,: er\B 表示单词中含有er,单独的以er结尾的词不行
    # 注意:\b 需要转意 即写成 \\b
    
    import re
    
    res=re.findall("海.","海燕海桥海石")   # ['海燕', '海桥', '海石']
    res=re.findall("^海.","海燕海桥海石")  # 海燕
    res=re.findall("海.$","海燕海桥海石")  # 海石
    res=re.findall("^海.$","海燕海桥海石") # []
    res=re.findall("^海.$","海燕") # ['海燕']  这就能明白为什么 . 也属于边界字符了
    
    print(res)
    
    

    分组()与或 |[^]

    身份证号码是一个长度为15或18个字符的字符串,如果是15位则全部由数字组成,首位不能为0;
    	如果是18位,则前17位全部是数字,末位可能是数字或x,下面我们尝试用正则来表示:
    

    在这里插入图片描述

    # 匹配任意一个邮箱 min@163.com
    # x|y 表示匹配 x 或者 y
    # (xyz) 加上括号表示将 xyz 看成一个整体
    mailPattern = "\w+@\w+\.\w+"
    # mailPattern = "(\w+@\w+\.((com)|(cn)))" # 在re.match / re.search 下能找出
    
    # 匹配日期 1800-01-01 --- 2020-12-31
    # 1899 1999 -- 2020
    # 0-[1-9] 1[0-1-2]
    # 0-[1-9] 1 2 - 0-9 3 0,1
    
    
    result=re.search("^((1[89]\d{2})|(20[01]\d)|(2020))-((0[1-9])|(1[012]))-((0[1-9])|([12]\d)|(3[01]))$","2020-12-31")
    # 注意括号分组,或 | 的时候,每一种可能给一个括号,
    # 判断的每一项(年、月、日)再给一个括号
    print(result)
    
    
    import re
    
    strd = input("请按格式输入出生年月日:")
    if re.search("((1[89]\d{2})|(20[01]\d)|(2020))-((0[1-9])|(1[012]))-((0[1-9])|([12]\d)|(3[01]))", strd):
        print("输入正确")
    else:
        print("输入格式有误,或者数值有误")
    
    

    转义字符

    在这里插入图片描述

    贪婪模式和非贪婪模式

    贪婪匹配:在满足匹配时,匹配尽可能长的字符串,默认情况下,采用贪婪匹配

    import re
    
    res = re.findall("a?", "min is a good man")  # 非贪婪模式
    # 结果:['', '', '', '', '', '', '', 'a', '', '', '', '', '', '', '', 'a', '', '']
    res = re.findall("a?", "min is a good maan")  # 非贪婪模式
    # 结果:['', '', '', '', '', '', '', 'a', '', '', '', '', '', '', '', 'a', 'a', '', '']
    res = re.findall("a*", "min is a good maan")  # 贪婪模式
    # 结果:['', '', '', '', '', '', '', 'a', '', '', '', '', '', '', '', 'aa', '', '']
    res = re.findall("a+", "min is a good maan")  # 贪婪模式
    # 结果:['a','aa']
    res = re.findall("a{3}", "min is a good maaan")  # 贪婪模式
    # 结果:['aaa']
    res = re.findall("a{3}", "min is a good maaaan")  # 贪婪模式
    # 结果:['aaa']
    res = re.findall("a{3,5}", "min is a good maaaaan")  # 贪婪模式
    # 结果:['aaaaa'] 包后
    res = re.findall("a{3,}", "min is a good maaaaaaan")  # 贪婪模式
    # 结果:['aaaaaaa']
    res = re.findall("a{,5}", "min is a good maaaaaaan")  # 贪婪模式
    # 结果:['', '', '', '', '', '', '', 'a', '', '', '', '', '', '', '', 'aaaaa', 'aa', '', '']
    print(res)
    
    

    单独出现 ? 非贪婪模式
    出现 的第二个范围量词是“ ?” 就会变成 非贪婪模式

    常用的非贪婪匹配Pattern

    *? 重复任意次,但尽可能少重复
    +? 重复1次或更多次,但尽可能少重复
    ?? 重复0次或1次,但尽可能少重复
    {n,m}? 重复n到m次,但尽可能少重复
    {n,}? 重复n次以上,但尽可能少重复
    

    . * ? 的用法

    . 是任意字符
    * 是取 0 至 无限长度
    ? 是非贪婪模式。
    合在一起就是:取尽量少的任意字符,一般不会这么单独写,他大多用在:
    .*?x
    
    就是取前面任意长度的字符,直到一个 x 出现
    

    re模块下的常用方法

    三种模式:
    re.match() 是从源字符串的 起始位置开始查找一个匹配项
    re.search() 是从源字符串中找到一个匹配项
    re.findall() 是从源字符串中找到所有的匹配项

    flag:真正的含义
    	re.I 	使匹配对大小写不敏感
     	re.M 	多行匹配,是否影响 ^ 和 $  
    	re.S 使 . 匹配包含换行符在内的任意字符
    
    # re.M 实例
    import re
    
    res = re.findall("^min","min is a good man\nmin is a good man") # ['min']
    res = re.findall("^min", "min is a good man\nmin is a good man", re.M)  # ['min', 'min']
    
    # 如果后面,没有加上re.M 表示看做一行字符串(不会进行换行),只能找到前面的一个“min”,加了,加了能找到两个
    
    res = re.findall("\Amin","min is a good man\nmin is a good man")  # ['min']
    res = re.findall("\Amin","min is a good man\nmin is a good man",re.M) # ['min', 'min']
    
    
    # print(res)
    

    re.match()

    re.match(pattern,string,flag) # 是从源字符串的 起始位置开始查找一个匹配项
    
         pattern 要进行匹配的正则表达式
         string 表示的是源字符串
         flag 标记, 可以不写
             re.I 使匹配对大小写不敏感
             re.M 多行匹配,是否影响 ^ 和 $
             re.S 使 . 匹配包含换行符在内的任意字符
    
    # 如果匹配成功会返回一个对象
    # 如果匹配失败 会 返回None
    # 可以根据 结构是否为 None 来判断是否匹配成功
    # 可以通过这个变量的group方法来获取结果;
    # 如果没有匹配到,会返回None,此时如果使用group会报错
    
    res = re.match("www","www.baidu.com")
    res = re.match("www","aww.baidu.com")
    res = re.match("www","awww.baidu.com")
    res = re.match("www","wwbaidu.www,com")
    res = re.match("www","wwwwbaidu.www,com")
    res = re.match("www","WWW.baidu.com")
    res = re.match("www","WWW.baidu.com",re.I)
    print(res)
    print(type(res))
    
    
    >>> 匹配手机号码
    import re
    phone_number = input('please input your phone number : ')
    if re.match('^(13|14|15|18)[0-9]{9}$',phone_number): # 如果成功则不是None
            print('是合法的手机号码')
    else:
            print('不是合法的手机号码')
            
    

    re.search()

    re.search(pattern,string,flag) # 是从源字符串中(从左往右)找到第一个匹配项
    
         pattern 要进行匹配的正则表达式
         string 表示的是源字符串
         flag 标记, 可以不写
             re.I 使匹配对大小写不敏感
             re.M 多行匹配,是否影响 ^ 和 $
             re.S 使 . 匹配包含换行符在内的任意字符
             
         # 多用于表单验证    
    
    res = re.search("www","www.baidu.com")
    res = re.search("www","ww.baiduwww.com")
    res = re.search("www","www.baiduwww.com")
    print(res)
    
    print(res.group)
    # 只匹配从左到右的第一个,得到的不是直接的结果,而是一个变量,
    # --需要通过这个变量的group方法来获取结果;
    # 如果没有匹配到,会返回None,此时如果使用group会报错
    

    re.findall()

    re.findall(pattern,string,flag) # 是从源字符串中找到所有的匹配项
    
         pattern 要进行匹配的正则表达式
         string 表示的是源字符串
         flag 标记, 可以不写
             re.I 使匹配对大小写不敏感
             re.M 多行匹配,是否影响 ^ 和 $
             re.S 使 . 匹配包含换行符在内的任意字符
    
    # findall的结果是列表的形式,会将找到的多个结果放到列表中去
    # 注意: 如果找不到,会返回一个空列表
    # 注意:不能直接使用 group 方法
    res = re.findall("www","www.baidu.com")
    res = re.findall("wwwa","www.baiduwww.com") # 结果:[]
    print(res)
    print(type(res))
    

    findall 的优先级查询:

    import re
    
    ret = re.findall('www.(baidu|oldboy).com', 'www.oldboy.com')
    print(ret)  # ['oldboy'] 这是因为findall会优先把匹配结果组里内容返回
    
    # 如果想要匹配结果,取消权限即可,格式:在分组内加上 ?:即 (?:正则表达式)
    
    ret = re.findall('www.(?:baidu|oldboy).com', 'www.oldboy.com')
    print(ret)  # ['www.oldboy.com']
    
    >>> 三种模式练习
    import re
    
    ret = re.findall('a', 'eva egon yuan') # 返回所有满足匹配条件的结果,放在列表里
    print(ret) # 结果 : ['a', 'a']
    
    ret = re.search('a', 'eva egon yuan').group()
    print(ret) # 结果 : 'a'
    # 函数会在字符串内 查找模式匹配,只到找到第一个匹配然后返回一个包含匹配信息的对象,
    # 该对象可以通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回None。
    
    ret = re.match('a', 'abc').group() # 同search,不过在字符串开始处进行匹配
    print(ret)
    #结果 : 'a'
    

    re.split()

    # re.split()
    # 参数:
    # pattern,正则表达式, 即以某个正则来拆分
    # string, 被拆分的源字符串
    # maxsplit=0, 最大拆分次数
    # flags=0 标识
    
    
    # 正则表达式来拆分字符串
    strData ="wen1 is2 a3 old4 man5"
    lis_re = re.split(" ",strData)
    # list_re=re.split("\d",strData)
    # list_re=re.split("[0-9]",strData)
    # list_re=re.split(" +",strData) #注意,+前面有个空格
    # print(listRes) 结果:['wen1', 'is2', 'a3', 'old4', 'man5']
    # 结果:['wen', ' is', ' a', ' old', ' man', '']
    
    # 如果想保留用来作切割标准的字符串:只需给它添加分组即可
    ret = re.split('\d+','alex83taibai40egon25')
    print(ret) # ['alex', 'taibai', 'egon', ''] # 最后一次切割 留下末尾一个空
    ret = re.split('(\d+)','alex83taibai40egon25aa')
    print(ret) # ['alex', '83', 'taibai', '40', 'egon', '25', 'aa']
    
    # split的优先级查询
    ret=re.split("\d+","eva3egon4yuan")
    print(ret) #结果 : ['eva', 'egon', 'yuan']
    
    ret=re.split("(\d+)","eva3egon4yuan")
    print(ret) # 结果 : ['eva', '3', 'egon', '4', 'yuan']
    
    # 在匹配部分加上()之后所切出的结果是不同的,
    # 没有()的没有保留所匹配的项,但是有()的却能够保留了匹配的项,
    # 这个在某些需要保留匹配部分的使用过程是非常重要的。
    

    re.sub()

    str= "蔡徐篮球 是 xxx\n蔡徐坤歌手 是 yyy\n 肖战 是 帅哥"
    
    # re.sub()
    # 参数 
    	pattern
    	repl, 用来替换的新字符串
    	string
    	count=0, 替换的次数,默认是全部替换
    	flags=0  # 不能修改,默认可以不写
    	# 默认是 re.M 模式,会换行匹配所有
    
    res = re.sub("蔡徐.{,2}","肖战",str)
    '''
    肖战 是 xxx
    肖战手 是 yyy
     肖战 是 帅哥
    '''
    
    # subn与sub功能一致, 但是 sub是返回替 换后的新字符串,
    
    # subn返回的是元组,元组有2个元素, 元素1代表替换后的新字符串, 元素2代表的替换的次数
    res = re.subn("蔡徐.{,2}","肖战",str)
    # ('肖战 是 xxx\n肖战手 是 yyy\n 肖战 是 帅哥', 2) 
        
    print(res)
    
    

    提取与分组

    正则表达式不仅仅有强大的匹配功能,还有强大提取功能
    (xyz) 将xyz看作一个整体
    (xyz) 将xyz看成一个小组
    

    re.search() 模式下的分组

    import re
    
    s = '<a>wahaha</a>'  # 标签语言 html 网页
    ret = re.search('<(\w+)>(\w+)</(\w+)>',s)
    print(ret.group(0))  # 所有的结果
    print(ret.group(1)) # 数字参数代表的是取对应分组中的内容
    print(ret.group(2))
    print(ret.group(3))
    

    re.findall() 模式的分组

    # 为了findall也可以顺利取到分组中的内容,有一个特殊的语法,就是优先显示分组中的内容
    ret = re.findall('(\w+)',s)
    print(ret) #['a', 'wahaha', 'a']
    ret = re.findall('>(\w+)<',s)
    print(ret) #['wahaha']
    
    strData = "010-34545546"
    numberPattern = "(\d{3})-(\d{8})" 结果:[('010', '34545546')]
    numberPattern = "((\d{3})-(\d{8}))" 结果:[('010-34545546', '010', '34545546')]
    # findall会将所有的组作为一个元组的元素,放在列表中,组是靠括号来分的
    res = re.findall(numberPattern,strData)
    print(res) # print(res[0]) 结果:('010', '34545546')
    

    re.findall模式下,取消分组优先

    ret = re.findall('\d+(\.\d+)?','1.234*4.3')
    print(ret) # 结果是:['.234', '.3']
    # 为什么只显示了 小数位,因为findall优先显示分组中的内容
    
    # 取消分组优先做法:在分组内加上?:(?:正则表达式)
    ret = re.findall('\d+(?:\.\d+)?','1.234*4.3')
    print(ret)
    
    
    str_date = "010-34545546"
    numberPattern = "\d{3}-\d{8}"
    numberPattern = "(\d{3})-(\d{8})"
    numberPattern = "((\d{3})-(\d{8}))"
    numberPattern = "(?P<First>\d{3})-(?P<Last>\d{8})"
    
    res = re.match(numberPattern,str_date)
    print(res)
    
    # group可以提取完整匹配的字符
    # () 可以将字符串分成多个组, 分组顺序是由外到里, 由前到后
    print(res.group()) # 默认是0
    print(res.group(1)) # 第一组
    print(res.group(2)) # 第二组
    #print(res.group(3)) # 第三组
    
    >>>可以给每一个分组取一个别名, 格式:(?P<别名>正则)
    # 获取的时候可以直接根据别名来获取
    print(res.group("First"))
    print(res.group("Last"))
    
    # groups 将() 包裹的内容进行分组提取, 将所有的分组作为元组的元素,并作为结果返回
         # 它只看括号
    res=re.match("\d{3}-\d{8}",strDate) # 这里没括号,输出结果为:()空元祖
    print(res.groups())
    

    分组命名的用法

    s = '<a>wahaha</b>' # 加入div标签不一致
    pattern = '<(\w+)>(\w+)</(\w+)>'
    ret = re.search(pattern,s)
    # print(ret.group(1) == ret.group(3)) False
    
    # 使用前面的分组 要求使用这个名字的分组和前面同名分组中的内容匹配的必须一致
    pattern = '<(?P<tab>\w+)>(\w+)</(?P=tab)>'
    ret = re.search(pattern,s)
    print(ret) #False
    
    >>>练习
    # 2018-12-06  这种时间格式,中间的分隔符必须一致,所以可以用到命名分组
    # 2018.12.6
    # 2018 12 06
    # 12:30:30
    

    总结

    import re
    
    ret = re.findall('a', 'eva egon yuan')  # 返回所有满足匹配条件的结果,放在列表里
    print(ret) # 结果 : ['a', 'a']
    
    ret = re.search('a', 'eva egon yuan').group()
    print(ret) # 结果 : 'a'
    # 函数会在字符串内查找模式匹配,只到找到第一个匹配然后返回一个包含匹配信息的对象,该对象可以
    # 通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回None。
    
    ret = re.match('a', 'abc').group()  # 同search,不过尽在字符串开始处进行匹配
    print(ret)
    # 结果 : 'a'
    
    ret = re.split('[ab]', 'abcd')  # 先按'a'分割得到''和'bcd',在对''和'bcd'分别按'b'分割
    print(ret)  # ['', '', 'cd']
    
    ret = re.sub('\d', 'H', 'eva3egon4yuan4', 1) # 将数字替换成'H',参数1表示只替换1个
    print(ret) # evaHegon4yuan4
    
    ret = re.subn('\d', 'H', 'eva3egon4yuan4') # 将数字替换成'H',返回元组(替换的结果,替换了多少次)
    print(ret)
    
    obj = re.compile('\d{3}')  # 将正则表达式编译成为一个 正则表达式对象,规则要匹配的是3个数字
    ret = obj.search('abc123eeee') # 正则表达式对象调用search,参数为待匹配的字符串
    print(ret.group())  # 结果 : 123
    
    import re
    ret = re.finditer('\d', 'ds3sy4784a')   # finditer返回一个存放匹配结果的迭代器
    print(ret)  # <callable_iterator object at 0x10195f940>
    print(next(ret).group())  # 查看第一个结果
    print(next(ret).group())  # 查看第二个结果
    print([i.group() for i in ret])  # 查看剩余的左右结果
    
    '''
    先编译后使用
    
    re模块的进阶 : 时间/空间
    compile 节省你使用正则表达式解决问题的时间
    编译 正则表达式 编译成 字节码
    在多次使用的过程中 不会多次编译
    ret = re.compile('\d+')   # 已经完成编译了
    print(ret)
    
    res = ret.findall('alex83taibai40egon25')
    print(res) # 类型是“list”
    res = ret.search('sjkhk172按实际花费928')
    print(res.group())
    
    
    
    finditer 节省你使用正则表达式解决问题的空间/内存
    ret = re.finditer('\d+','alex83taibai40egon25')
    #print(ret)这是一个迭代器
    for i in ret:
         print(i.group())
    
    
    findall 返回列表 找所有的匹配项
    search  匹配就 返回一个变量,通过group取匹配到的第一个值,不匹配就返回None,group会报错
    match   相当于search的正则表达式中加了一个'^'
    
    spilt   返回列表,按照正则规则切割,默认匹配到的内容会被切掉
    sub/subn 替换,按照正则规则去寻找要被替换掉的内容,subn返回元组,第二个值是替换的次数
    
    compile  编译一个正则表达式,用这个结果去search match findall finditer 能够节省时间
    finditer 返回一个迭代器,所有的结果都在这个迭代器中,需要通过循环+group的形式取值 能够节省内存
    '''
    

    应用

    匹配标签

    import re
    
    
    ret = re.search("<(?P<tag_name>\w+)>\w+</(?P=tag_name)>","<h1>hello</h1>")
    # 还可以在分组中利用?<name>的形式给分组起名字
    # 获取的匹配结果可以直接用group('名字')拿到对应的值
    print(ret.group('tag_name'))  # 结果 :h1
    print(ret.group())  # 结果 :<h1>hello</h1>
    
    ret = re.search(r"<(\w+)>\w+</\1>","<h1>hello</h1>")
    # 如果不给组起名字,也可以用\序号来找到对应的组,表示要找的内容和前面的组内容一致
    # 获取的匹配结果可以直接用group(序号)拿到对应的值
    print(ret.group(1))
    print(ret.group())  # 结果 :<h1>hello</h1>
    
    # 正则匹配所有所有tag
    <[^>]+> # [^>]+ 指除了“>”外,但是至少有一个字符
    
    # 匹配 open tag 
    <[^/][^>]*> 
    # 匹配 close tag
    </[^>]+>
    
    # 匹配 单标签
    <[^>]+/>
    

    在这里插入图片描述

    import re
    s="<img src='http://somehost/picture'/>"
    ret=re.search("<[^>]+>",s).group()
    print(ret) # <img src='http://somehost/picture'/>
    
    # 匹配 双/单 引号
    "[^"]*"  # 双/单 引号 中可以是没有任何内容
    

    在这里插入图片描述

    爬虫实例:爬取豆瓣排名前250的电影

    import re
    from urllib.request import urlopen
    
    def getPage(url): # 获取网页的字符串
         response = urlopen(url)
         return response.read().decode('utf-8')
    
    def parsePage(s):
         ret = com.finditer(s) # 从s这个网页源码中 找到所有符合com正则表达式规则的内容 并且以迭代器的形式返回
         for i in ret:
             yield {
                 "id": i.group("id"),
                 "title": i.group("title"),
                 "rating_num": i.group("rating_num"),
                 "comment_num": i.group("comment_num"),
             }
    
    def main(num): # 0 25 50 #这个函数执行10次,每次爬取一页的内容
         url = 'https://movie.douban.com/top250?start=%s&filter=' % num #每次等于多少页
         response_html = getPage(url) # response_html就是这个url对应的html代码 就是 str
         ret = parsePage(response_html) # ret是一个生成器
         #print(ret)
         f = open("move_info7", "a", encoding="utf8")
         for obj in ret:
             print(obj)
             data = str(obj)
             f.write(data + "\n")
         f.close()
    
    
    com = re.compile(
             '<div class="item">.*?<div class="pic">.*?<em .*?>(?P<id>\d+).*?<span class="title">(?P<title>.*?)</span>'
             '.*?<span class="rating_num" .*?>(?P<rating_num>.*?)</span>.*?<span>(?P<comment_num>.*?)评价</span>', re.S)
    
    #.*? 的使用,遇到什么停止,加上 re.S模式;把要用的内容分组好
    
    
    count = 0
    for i in range(10):
         main(count)
         count += 25
    

    对照标签

    在这里插入图片描述

    匹配整数

    import re
    
    ret=re.findall(r"\d+","1-2*(60+(-40.35/5)-(-4*3))")
    print(ret) # ['1', '2', '60', '40', '35', '5', '4', '3']
    ret=re.findall(r"-?\d+\.\d*|(-?\d+)","1-2*(60+(-40.35/5)-(-4*3))")
    print(ret) # ['1', '-2', '60', '', '5', '-4', '3']
    ret.remove("")
    print(ret) # ['1', '-2', '60', '5', '-4', '3']
    
    匹配一个整数:\d+
    匹配一个小数:\d+\.\d+
    匹配一个整数或者小数:\d+\.\d+ | \d+  或者  \d+(\.\d+)?
    

    数字匹配

    >>>匹配一段文本中的每行的邮箱
         # 只允许英文字母、数字、下划线、英文句号、以及中划线组成
         # 例:zhoujielun-001@gmail.com
         ^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$
         
         # 名称允许汉字、字母、数字,域名只允许英文域名
         # 例:周杰伦001Abc@lenovo.com.cn
         ^[A-Za-z0-9\u4e00-\u9fa5]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$
    
    	# 邮箱规则:
    	# @之前必须有内容且只能是字母(大小写)、数字、下划线(_)、减号(-)、点(.)
    	# @和最后一个点(.)之间必须有内容且只能是字母(大小写)、数字、点(.)、减号(-),
    	# --且两个点不能挨着
    	# 最后一个点(.)之后必须有内容且内容只能是字母(大小写)、数字且长度为大于等于2个字
    	# --节,小于等于6个字节
    
    	[0-9a-zA-Z][\w\-.]+@[a-zA-Z0-9\-]+(\.[a-zA-Z0-9\-]+)*\.[A-Za-z0-9]{2,6}
    
         
    >>>匹配一段文本中的每行的时间字符串,比如:‘1990-07-12’;
    
       分别取出1年的12个月(^(0?[1-9]|1[0-2])$)、
       一个月的31天:^((0?[1-9])|((1|2)[0-9])|30|31)$
    
    >>>匹配qq号。(腾讯QQ号从10000开始)1,9[0,9]{4,}
    
    >>>匹配一个浮点数。       ^(-?\d+)(\.\d+)?$   或者  -?\d+\.?\d*
    
    >>>匹配汉字。             ^[\u4e00-\u9fa5]{0,}$ 
    
    >>>匹配出所有整数 
    
    
    >>> 1-2*((60-30+(-40/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))
    	# 从上面算式中匹配出内层没有其他小括号的表达式
    	\([^()]+\)
    
    >>>从类似9-1000/3+7/3*99/4*2998+10*568/14的表达式中匹配出从左到右第一个乘法或除法
    	\d+[*/]\d+
    

    模拟一个计算器功能

    import re
    
    
    def atmo_cal(exp):  # 原子计算器,最小单位不可再拆分了,处理乘除法,如:5*0.6;6/2
        if "*" in exp:
            a, b = exp.split("*")  # 最小了,只有两位
            return str(float(a) * float(b))
        elif "/" in exp:
            a, b = exp.split("/")
            return str(float(a) / float(b))
    
    
    def add_sub(exp):  # 计算加减法
        ret = re.findall("[-+]?\d+(?:\.\d+)?", exp)  # 取消分组优先,得到一个列表
        exp_sum = 0
        for i in ret:
            exp_sum += float(i)
        return exp_sum
    
    
    def mul_div(exp):  # 计算乘除法
        while True:
            ret = re.search("\d+(?:\.\d+)?[/*]-?\d+(?:\.\d+)?", exp)
            # 用的是search,所以从左往右匹配到第一项就返回结果
            if ret:
                atmo_exp = ret.group()  # 分组取出原子每一项
                res = atmo_cal(atmo_exp)  # 调用原子计算器,打印结果为"-22.0"
                # "2-1*-22+3-4/-5" "-22.0" 替换原式子中的位置即:"2--22.0-3-4/-5"
                exp = exp.replace(atmo_exp, res)  # 参数位置 旧的,新的 将旧的替换成新的
            else:  # 2--22.0-3--0.8 乘除法都运算完毕了
                return exp
    
    
    def format(exp):
        exp = exp.replace('--', '+')
        exp = exp.replace('+-', '-')
        exp = exp.replace('-+', '-')
        exp = exp.replace('++', '+')
        return exp
    
    
    def cal(exp):  # 将乘法或者除法匹配出来;"2-1*-22-3-4/-5" 用来计算用的
        exp = mul_div(exp)  # 调用乘除法函数
        exp = format(exp)  # 调用格式化函数后:2+22.0-3+0.8
        exp_sum = add_sub(exp)  # 调用计算加法的函数 21.8
        return exp_sum  # 返回结果
    
    
    # print(cal("2-1*-22-3-4/-5"))
    
    
    def main(exp):  # 主函数
        exp = exp.replace(" ", "")  # 去掉用户输入内容的空格
        while True:
            ret = re.search("\([^()]+\)", exp)  # (-40/5)
            if ret:
                inner_bracket = ret.group()  # 这里可能得到各种运算
                res = str(cal(inner_bracket))
                # print(inner_bracket,type(res))
                exp = exp.replace(inner_bracket, res)
                # print(exp) 再格式化下 1-2*((60-30+-8.0*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))
                exp = format(exp)
                # print(exp)
            else:
                break
        # print(exp,type(exp)) ;1-2*-1388335.8476190479 <class 'str'>
        return cal(exp)
    
    
    s = '1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )'
    ret = main(s)
    print(ret, type(ret))
    print(eval(s), type(eval(s)))  # 用户可能再用到,所以像eval一样返回原来的格式
    # 2776672.6952380957 <class 'float'>
    # 2776672.6952380957 <class 'float'>
    
    展开全文
  • 快速入门 import re pattern = 'this' text = 'Does this text match the pattern?' match = re.search(pattern, text) s = match.start() e = match.end() print('Found {0}\nin {1}'....#python re_simple_matc
  • 正则表达式re.compile() compile()的定义: compile(pattern, flags=0) Compile a regular expression pattern, returning a pattern object. 从compile()函数的定义中,可以看出返回的是一个匹配对象,它单独使用...
  • 效果演示: END 结语 今天的分享到此结束了,结束了Python面向对象的学习,我们开始了正则化表达式的函数使用,re.match() 仅仅只是其中一个个例,正则化匹配还有很多类似的函数,大家可以自行学习哦,原理都是相同...
  • 正则大同小异,python 中的正则跟其他语言相比略有差异: 1、替换字符串时,替换的字符串可以是一个函数 2、split 函数可以指定分割次数,这会导致有个坑 3、前项界定的表达式必须定长 下面详细描述下 re 模块的使用...
  • 一般来说url地址前几位为 http,https或ftp 后面跟:// 再之后可出现任意...#匹配url地址 ... res = re.match("(http|https|ftp)://[^\s]+", url) print(res.group()) 输出结果为 https://www.baidu.com Process fin...
  • 首先,运行 Python 解释器,导入 re 模块并编译一个 RE: #!python Python 2.2.2 (#1, Feb 10 2003, 12:57:01) >>> import re >>> p = re.compile(‘[a-z]+’) >>> p <_sre.SRE_Pattern object at 80c3c28> 现在...
  • python re模块(正则表达式) sub()函数详解

    万次阅读 多人点赞 2019-05-14 20:21:38
    Python中的正则表达式方面的功能,很强大。 其中就包括re.sub,实现正则的替换。 功能很强大,所以导致用法稍微有点复杂。 所以当遇到稍微复杂的用法时候,就容易犯错。 所以此处,总结一下,在使用re.sub的时候,...
  • 本模块提供了和Perl里的正则表达式类似的功能,不关是正则表达式本身还是被搜索的字符串,都可以是Unicode字符,这点不用担心,python会处理地和Ascii字符一样漂亮。 正则表达式使用反斜杆(\)来转义特殊字符,使其...
  • Python3正则表达式:match函数

    千次阅读 2019-04-23 23:42:57
    import re ... ...re_compile = re.compile("www") # match从起始位置开始匹配,且只匹配一次,如果不没找到...match = re_compile.match(url) # .span用来获取匹配到的字符串所对应的下标位置 #re_compile.match(url)...
  • python3中的RE(正则表达式)-总结

    万次阅读 多人点赞 2018-07-24 20:57:56
    要使用python3中的RE则必须引入 re模块 import re #引入正则表达式 2.主要使用的方法 match(), 从左到右进行匹配 #pattern 为要校验的规则 #str 为要进行校验的字符串 result = re.match(pattern, str) #...
  • 揭秘match(), search(), finall()的区别,废话不多说,看...str_match2 = re.match(r'python(.*)!', str) print(str_match2.span()) # 返回(0, 22) print(str_match2.group()) # 返回 python是世界上最美的语言!我爱
  • re.match 尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none。 函数语法: re.match(pattern, string, flags=0) 函数参数说明: 参数 描述 ...
  • /usr/bin/python # # -*- coding: UTF-8 -*- import re number = "123-456-789 # test" num = re.sub(r'#.*$',"",number) print("电话:",num) num = re.sub(r"\D","",number) print("phone:",num) def double...
  • demo.py(正则表达式,match从开头匹配,分组,分组别名): # coding=utf-8 import re # 小括号()表示分组 \1表示取出第一个分组中匹配的字符串。 ret = re.match(r"&lt;(\w*)&gt;&lt;(\w*)&...
  • re.search与re.match可以实现正则匹配,返回字符串中第一个符合正则表达式的字符串段,无匹配时返回None。其中re.match从头开始匹配,re.search()从任意位置开始匹配。 具体见:正则---re模块的基础用法(re.match()...
  • 1,re模块之match的基本使用 ** 1,可使用re模块,通过正则表达式对字符串进行匹配 2,re.match函数 尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none。 3,函数语法为:...
  • re.search方法 re.search 扫描整个字符串并返回第一个成功的匹配。 函数语法: re.search(pattern, string, flags=0)   函数参数说明: 参数描述 pattern 匹配的正则表达式 string 要...
  • 主要介绍了Python3中正则模块re.compile、re.matchre.search函数用法,结合实例形式较为详细的分析了re模块 中re.compile、re.matchre.search函数的功能、参数、具体使用技巧与注意事项,需要的朋友可以参考下
  • import re ''' url :&amp;amp;amp;quot;http://money.163.com/special/pinglun/&amp;amp;amp;quot; 抓取第一页的新闻信息,并按照以下规格输出。 [ {'title':'生鲜电商为何难盈利?','created_at':'2013-...
  • 正则表达式 导入模块import re match()从左往右,从起始部分开始匹配 1.单字符匹配打印----match()方法,group()方法 text = 'python' reslut = re.match('py', text) # 结果存储在一个Object对象里,使用group打印 ...
  • python 正则表达式 python re模块的使用

    千次阅读 2017-05-07 16:56:04
    python正则表达式,python re模块 一、re.match() 用正则表达式模式从字符串开头开始匹配 二、re.search() 在字符串中查找表达式第一次出现 三、re.sub() 检索替换 四、re.split() 字符串分割 五、re.findall...
  • python re正则表达式匹配规则

    万次阅读 2018-10-31 18:10:17
    不同的语言具有不同的使用正则表达式方法,python是通过re来实现的。 re.serach() re.search(r’re_compile‘,strings) For instance import re re.search(r'lk12','I love lk12') Out[54]: ...
  • Python正则表达式_re模块

    千次阅读 2019-01-23 00:57:37
    s1 = 'Python是一门简单的语言' print(s1.find('简单')) # 9 # 匹配满足的第一个字符的索引 # 2,正则匹配: # 单个字符匹配 import re # \w 与 \W # print(re.findall('\w', '宝元meet 12*() _'))...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 33,741
精华内容 13,496
关键字:

match正则pythonre

python 订阅