zoukankan      html  css  js  c++  java
  • 正则表达式-入门初探

    最近处理数据,看开源代码满屏幕的正则表达式,脑壳疼。

    花了一整天时间看 菜鸟教程 的正则表达式……感觉写的有点过于详细,而且顺序也让我很迷惑……

    于是自己写点总结吧。

    • 我觉得首先要搞懂的是,正则表达式其实就是一个字符串的模板,用来在字符串中寻找符合条件的子串。下面是一个最简单的例子,用来在字符串中寻找‘1234’子串。
    import re
    
    myre = re.compile(r'1234')
    
    mystr = 'xx1234yy'
    
    myres = myre.search(mystr)
    
    print(myres)
    
    '''
    <_sre.SRE_Match object; span=(2, 6), match='1234'>
    '''
    start
    • 相信大家开始学正则表达式的时候,肯定是突然有一个某个需求,然后找到其他人的代码,又想看懂吧。里面肯定各种大中小括号,让人头大2333333

    不过先别急,先给出两个简单的概念,普通字符(例如,a 到 z 之间的字母)和特殊字符(称为"元字符")。

    所谓的特殊字符(元字符),其实就是一些字符给了一些特殊的意义,有点类似于保留字、系统自带函数之类的东西,而且不允许你重载它。如果你想在正则表达式中匹配特殊字符本身,只需要在它之前加一个就行了,比如*就是匹配的*,但是单独的*就会发挥它的特定功能。具体有哪些特殊字符,可以参考这个菜鸟教程网页 。刚开始学没必要把它们都弄懂,只要把  + * 大中小括号先弄懂,就能写一些基本的正则表达式了。其他的后续碰到再查表就是了。

    • 我觉得有必要先弄懂大中小括号。
    • 先讲中括号[],中括号是一个字符簇。中括号要注意的就是,一个中括号虽然可以表达一个很大的范围(字符簇),但是它只能在字符串中匹配单一的一个字符。

        看下面的例子。

    r'[AaEeIiOoUu]'
    #这个模式与任何单个的元音字符匹配,但只能匹配一个字符。
    
    #用连字号-可以表示一个字符的范围,如下
    r'[a-z]' #匹配所有的单个小写字母 
    r'[A-Z]' #匹配所有的单个大写字母 
    r'[a-zA-Z]' #匹配所有的单个字母 
    r'[0-9]' #匹配所有的单个数字 
    r'[0-9.-]' #匹配所有的单个数字或句号或减号 
    #需要匹配连续的某字符簇的话,配合+或者*使用。如下
    
    r'[0-9]+'  #匹配0个或者连续多个0-9范围内的数字, 如‘1234’  或者 ‘’
    r'[0-9]*'  #匹配至少1个或连续多个0-9范围内的数字, 如‘1234’
    []

             看完这个中括号的例子,大概也能猜到+ 和*的作用了。

    • 然后是小括号(),小括号是用来标记一个子表达式的开始和结束位置。
    In [50]: myre = re.compile(r'([0-9][a-c])+')
    
    In [51]: mystr = '1c2a3b'
    
    In [52]: myres = myre.search(mystr)
    
    In [53]: print(myres)
    <_sre.SRE_Match object; span=(0, 6), match='1c2a3b'>
    
    In [54]: myre2 = re.compile(r'[0-9][a-c]+')
    
    In [55]: mystr2 = '1abbc'
    
    In [56]: myres2 = myre2.search(mystr2)
    
    In [57]: myres2
    Out[57]: <_sre.SRE_Match object; span=(0, 5), match='1abbc'>
    
    In [58]: myres3 = myre2.search(mystr)
    
    In [59]: myres3
    Out[59]: <_sre.SRE_Match object; span=(0, 2), match='1c'>
    ()

    这个例子解释了加()对+元字符的作用范围的功能。不加()的时候,只能匹配数字开头,至少1个abc的字符串。但是加了()之后,变成了匹配数字和abc交替出现的字符串。

    • 然后是大括号{}, 大括号是用来标记前一个子表达式匹配的次数,其实作用和+ * 有些类似,只不过有特定的次数。看下面的例子:
    '''
    一个数字 {x} 的意思是前面的字符或字符簇只出现x次 ;一个数字加逗号 {x,} 的意思是前面的内容出现x或更多的次数 ;两个数字用逗号分隔的数字 {x,y} 表示 前面的内容至少出现x次,但不超过y次。我们可以把模式扩展到更多的单词或数字:
    '''
    r'a{4}'        #匹配连续4个a
    r'a{2,}'      #匹配连续两个a的字符串
    r'a{2,4}'     #匹配连续a,至少两个,最多4个。
    {}

    其实特殊字符 * 与 {0,} 是相等的,它们都代表着 0 个或多个前面的子表达式 。特殊字符 + 与 {1,} 是相等的,表示 1 个或多个前面的子表达式。 

    我的入门初探小结大概就是这样了。能看懂上面这些的话,基本的正则表达式都能看懂了。

    看教程的过程中还看到一个  “贪婪”“非贪婪”的概念。

    这个东西其实也很好理解。下面给一个例子吧。

    _curly_re = re.compile(r'(.*?){(.+?)}(.*)')
    
    
    # 这个表达式,用小括号()分成了3部分,然后中间还有夹杂着{ }用来匹配左右大括号字符,而不是表示特殊符号大括号。
    
    #第一个小括号中的子表达式:
    #.表示通配符,匹配除换行符 
     之外的任何单个字符。
    #.后面加了一个*,表示匹配前面的子表达式零次或多次
    #.*结合起来就是匹配任意的符号0次或多次。
    #但是后面又加了一个?     这个?就是标志 非贪婪的匹配。
    # 什么叫非贪婪呢?
    
    #举例如下
    r'.*{'      #可以匹配'asdf{asdf{'
    r'.*?{'      #只能匹配到'asdf{xxx{'中的  'asdf{'子串
    
    #很好理解了吗? 非贪婪就是  .*对于这种可以无限往下匹配的表达式,会考虑后续表达式的匹配,而不是贪婪的无穷的匹配下去。
    贪婪、非贪婪
  • 相关阅读:
    使用Acctinfo.dll了解更多AD用户帐号信息
    vue elementUI之Form表单 验证
    vue element-ui 表格筛选,点击筛选数据
    使用Bootstrap + Vue.js实现 添加删除数据
    CSS3过渡效果 兼容IE6、IE7、IE8
    使用Ajax、json实现京东购物车结算界面的数据交互
    JavaScript面向对象,闭包内存图,闭包和作用域
    实现一个宽和高都是100像素的div可以用鼠标拖拽移动的效果
    JavaScript鼠标事件,点击鼠标右键,弹出div
    javascript sort排序
  • 原文地址:https://www.cnblogs.com/chengebigdata/p/9218148.html
Copyright © 2011-2022 走看看