美文网首页Python
python正则表达式必知必会

python正则表达式必知必会

作者: 不分享的知识毫无意义 | 来源:发表于2019-06-02 20:38 被阅读105次

      正则是做数据分析和挖掘必须要会的一种方法,会了它很多问题其实就可以高效的解决了。说一个最常用的应用场景,在文本识别中,使用正则可以快速识别出类似于qq号、广告、联系方式等内容,很简单就可以为网站文本过滤提供支持。

    1.正则表达式基础

      正则表达式有一套自己的语言系统,像人类语言一样,有几个关键字构成了它的基础语法。整理起来就是下面这几个:

    • \表示转义,一些特殊字符有特殊的意识,加\就可实现特定的意思。比如\d表示匹配数字,\s表示匹配任何不可见字符,如空格、制表符等。
    • .表示匹配任意字符,要匹配.自身,就需要转义用\.。
    • *表示匹配前面的字符0次或者多次,即即使一次不出现也无所谓。
    • +表示匹配前面的字符1次或者多次,即前面的字符至少要出现1次。
    • ?表示匹配前面的字符0次或者1次。
    • |表示或,可以匹配|前后的任意字符。
    • ^表示匹配字符串的开始位置,必须以^之后的字符开头的才能匹配。
    • $表示匹配字符串的结尾位置,必须以$之前字符结尾的才能匹配。
    • [^]当^出现在方括号里表示匹配非方括号内的任意一个字符。
    • {}表示匹配前面的字符几次,{3}表示匹配3次,{3,5}表示匹配3-5次,可以和[]一起使用。
    • <>匹配单词,如<the>可以匹配 the man中的the,却不能匹配otherwise中的the。
    • ()表示匹配一个整体,即括号里的内容必须都出现的时候才匹配,关于()还有很多衍生,实际中也比较有用。
    • (?:)非获取匹配,就是只匹配内容但却不输出,这个在re模块的fetchall中最常用,比如说industr(?:y|ies)这个能匹配industry也能匹配y但是最后只会输出industry而不输出y。
    • (?=pattern)这个也是非获取匹配,大意是先找pattern然后看之前的字符串符不符合正则,匹配完成后进行下一次的pattern匹配,也是只输出整体,而不单独输出pattern。比如Windows(?=95|98|NT|2000)能匹配Windows2000中的Windows而不能匹配Windows7中的Windows。
    • (?!pattern)这个和上面那个正好相反,在不匹配pattern的位置开始查找字符串。比如Windows(?=95|98|NT|2000)能匹配Windows7中的Windows而不能匹配Windows2000中的Windows。
    • (?<=pattern)这个东西太有意思了,和(?=pattern)是一样的,只不过方向是反的,啥意思呢,(?<=95|98|NT|2000)Windows)能匹配2000Windows里的Windows,却匹配不了7Windows里的Windows。
    • (?<!pattern),我想你已经猜到了,和(?!pattern)相同,只是方向是反的,例子我就不举了。
        会了这些,正则表达式你就入门了,剩下的看你的悟性了。

    2.正则表达式常用元字符

      其实第一部分讲的也是元字符,之所以把它们拿出来说是因为太重要了,如果对正则要求不咋严格的话,第一部分就足够解决大部分问题了。下面的我就简单介绍。

    • \b,匹配单词边界,如od\b,可以匹配good,但不能匹配odd。
    • \B,匹配非单词边界,如od\B,可以匹配odd,但不能匹配good。
    • \d,匹配一个数字,等同于[0-9]。
    • \D,匹配一个非数字,等同于[^0-9]。
    • \r,匹配回车符。
    • \n,匹配换行符,经常和\r一起用。
    • \f,匹配分页符。
    • \t,匹配制表符。
    • \s,匹配任何不可见的字符,包括空格,回车符,换行符等。
    • \S,匹配任何可见字符。
    • \w,匹配包括下划线的任意字母数字字符。
      -\W,匹配非下划线、数字、字母字符。
    • \p{P},匹配任意标点符号,还有其他的用法:L字母;M:标记符号(一般不会单独出现);Z:分隔符(比如空格、换行等);S:符号(比如数学符号、货币符号等);N:数字(比如阿拉伯数字、罗马数字等);C:其他字符。这个原生的python re包是不支持的,需要安装regex包才支持,这个包有很多高阶用法,我后面介绍。
        当然还有很多表达方式,不过不经常使用,如果要用的话可以去百度。

    3.python中自带的处理正则表达式的包—re

      开始之前,先说一下python对字符串的默认操作符,首先是字符串前加r,表示不转义,r"i am . frank",这个点就是代表点自身,还有一个是字符串前加u,代表采用unicode编码,对于中文的正则用的比较多。接下来说re中的函数。

    • re.compile()
        这个函数是对你写好的正则进行编译,用法就是compile(pattern, flags=0) ,它要和下面的函数搭配使用才能起作用。但是首先编译你写好的正则表达式是一种良好的编码习惯,可以使代码更整洁。
    • re.match()
        这个函数是根据写好的字符查找字符串中符合条件的部分,基本用法为re.match(pattern,str),要求必须从字符串的开头开始匹配,要提取值,可以用result.group()。这个得举例子来说了。
    import re
    regx1 = re.compile('\w{0,8}')
    result = re.match(regx1,'itcast.cn')
    #当然也可以用result = re.match('\w{0,8}','itcast.cn')
    print(result)
    -- 输出,注意它的输出是一个python对象,可以当逻辑判断使用
    <re.Match object; span=(0, 6), match='itcast'>
    
    • re.search()
      跟match作用类似,所不同的是不要求必须从字符串开头开始匹配,也就是说可以匹配字符串的任意位置,返回第一个成功的匹配,基本用法为:re.search(pattern, string, flags=0)。
    regx1 = re.compile('\d+')
    result = re.search(regx1,'abc 123itcast.cn522abc')
    print(result)
    -- 输出
    <re.Match object; span=(4, 7), match='123'>
    
    • re.findall()
        这个函数将以列表的形式返回所有匹配到的字符,因为返回的是字符列表所以比match函数要常用,基本用法为findall(pattern, string, flags=0),参数的含义和match一样,还是来看案例。
    regx2 = re.compile('[t,w]h')
    result = re.findall(regx2,'https://docs.python.org/3/whatsnew/3.6.html')
    print(result)
    --输出
    ['th', 'wh']
    

      这个函数有个坑我必须要说一下,就是如果有括号的话,那么括号里的内容都会匹配一遍。

    regx3 = re.compile(r'(.*([w]h).*)')
    result = re.findall(regx3,'https://docs.python.org/3/whatsnew/3.6.html')
    print(result)
    --输出
    [('https://docs.python.org/3/whatsnew/3.6.html', 'wh')]
    

      咋办呢,用第一部分的?:解决。

    regx4 = re.compile(r'(.*(?:[w]h).*)')
    result = re.findall(regx4,'https://docs.python.org/3/whatsnew/3.6.html')
    print(result)
    --输出
    ['https://docs.python.org/3/whatsnew/3.6.html']
    
    • re.split()
        这个函数的作用是以写好的正则表达式为分割符,对字符串进行分割后以列表形式返回分割之后的结果。
    regx4 = re.compile(r'\d+')
    print(regx4.split('one1two2three3four4'))
    -- 输出
    ['one', 'two', 'three', 'four', '']
    
    • re.sub()
        这是第一版介绍的最后一个函数,这个函数的作用是替换,返回的是匹配之后的结果。基本用法为re.sub(pattern, repl, string, count=0, flags=0)
      ,其中pattern,repl,string是必选参数,repl的意思是用什么字符串去替换正则匹配到的字符串。
    regx5 =re.compile( "\d+")
    result = re.sub(regx5, '_add111', 'hello 123 world 456 nihao 789',2)
    print(result)
    --输出
    hello _add111 world _add111 nihao 789
    

      还有一些高阶函数,如果我用上了,我会继续补充的,目前笔者工作中还是没有遇到的。

    4.3.python正则表达式进阶—regex

      这个包不是python自带的,需要pip install安装,安装很简单。它提供了很多附加的正则表达式功能。

    • 支持unicode代码属性,如u'[\u4e00-\u9fa5]'表示任意中文字符,\p{Cyrillic}表示西里尔字符,更多用法可以使用过程中百度。
    • 支持模糊匹配,有三种模式:i,模糊插入、d,模糊删除、s,模糊替换。
    import regex
    regex.findall('(?:hello){s<=2}', 'hallo')
    --输出
    ['hallo']
    
    • 支持可以复用的程序子句,用(?(DEFINE)...)进行操作
    regex.search(r'(?(DEFINE)(?P<quant>\d+)(?P<item>\w+))(?&quant) (?&item)', '5 elephants')
    -- 输出
    <regex.Match object; span=(0, 11), match='5 elephants'>
    

      此后可以用(?&quant)表示\d+,(?&item)表示\w+,特别适用于子句复杂的情况。
      更多功能待探索后补充。

    相关文章

      网友评论

        本文标题:python正则表达式必知必会

        本文链接:https://www.haomeiwen.com/subject/byyoaqtx.html