• 正则表达式


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

    简单说下python自己封装对象的功能

    查找c的下标
    "abc".find("c")
    
    拆分字符串
    "abc".split("b")
    
    替换字符串,将ab替换成cc
    "abcd".replace("ab","cc")

    上述功能都是很基本的,比如split如果想根据a或b分 这里就弄不了了。正则就是完成这些复杂的功能

    开始正则:

    # -*- coding:utf-8 -*-
    import re
    #查找
    #findall完全匹配。查找abc ,找到后返回列表
    print  re.findall("abc","aabasdwqeabc,abc")
    结果:
    ['abc', 'abc']

    findall默认优先匹配"()"组的内容,想去掉这个限制就加上:?

    >>> re.findall("www.(baidu|163).com","www.baidu.com")
    ['baidu']
    >>> re.findall("www.(?:baidu|163).com","www.baidu.com")
    ['www.baidu.com']

    元字符就是在正则中带有功能的字符,"abcdef"这类就没有特殊功能的就是普通字符。这些就是云字符了   . ^ $ * + ? { [ ] | ( )

    这里引用了一些别人总结的语法功能:下面的代码不会特意提示字符功能

    这里只会匹配1个字符,如果是abcaad就不行了

     >>> re.findall('abc.d','abcad12')

    ['abcad']

    ^这个符号有2个意思,这里就是匹配以abc开头的

    >>> re.findall('^abc','abcad12abc')
    ['abc']

    以abc结尾

    >>> re.findall('abc$','abcad12abc')
    ['abc']

    这里*匹配0个和多个(无限),*只会匹配临近的也就是c一个字符。 ab为什么能匹配出来是因为满足0个结果

    >>> re.findall('abc*','abad12abc')
    ['ab', 'abc']

    +匹配1到多次

    >>> re.findall('abc+','abad12abdabc')
    ['abc']

    ?匹配0-1次

    >>> re.findall('abc?','abad12abdabcabccccccccc')
    ['ab', 'ab', 'abc', 'abc']

    {}指定匹配次数,也可以写范围{3,5}  3-5次,B区间:就是包括3和5

    >>> re.findall('abc{3}','abad12abdabcabccccccccc')
    ['abccc']

    这个元字符记住下面规则:

    1反斜杠后边跟元字符去除特殊功能

    2反斜杠后边跟普通字符实现特殊功能

    3引用序号对应的字组所匹配的字符串

    这里先看看第三条比较不好理解

    这里()就是一个组,下面又2个组1就是组1,2就是组2 ,2=就等同于hello了,这样就不用在自己打这些字母了直接2即可就是方便。

    >>> re.search(r"(abc)de(hello)2","abcdehellohello").group()
    'abcdehellohello'

    根据第2第二条举个例子:

    提示:

    上面的取值都是一个值,如果是2位数及以上的就不会提取出来,这是d+就OK了

    >>> re.findall('d','acd123456')
    ['1', '2', '3', '4', '5', '6']

    匹配单词边界

    说白了这个功能就是要找一个词,hello空格。就是单词左右两侧包含空格。下面要注意在匹配的时候可以加r(原生字符)或\b表示

    >>> re.findall(r"hello"," hello wordhellodord")
    ['hello']

    这个就无法匹配改成\b即可
    >>> re.findall("hello"," hello wordhellodord")
    []

    字符集应用(元字符在字符集中无法使用变成普通方法了)

    匹配a[b或c]d 的模式

    >>> re.findall('a[bc]d','abd')
    ['abd']
    >>> re.findall('a[bc]d','acd')
    ['acd']
    >>>

    这三种^、-、仍然可以在字符集中应用   

    查找a-z或1-9,"-"在字符集中是有特殊意义的,指定范围

    >>> re.findall('[1-9]','acd1234561')
    ['1', '2', '3', '4', '5', '6', '1']
    >>> re.findall('[1-9]','acd123456')
    ['1', '2', '3', '4', '5', '6']

    >>> re.findall('[a-z,1-9]','acd123456')
    ['a', 'c', 'd', '1', '2', '3', '4', '5', '6']

    字符集中的"^"非的意思,匹配非0-9的数字

    >>> re.findall('[^1-9]','acd123456')
    ['a', 'c', 'd']

    匹配0-9数字

    >>> re.findall('[d]','acd123456')
    ['1', '2', '3', '4', '5', '6']

    非贪婪模式

    ?利用这个元字符了。提示这里测试需要用re.search不能用re.findall,findall 返回的都是列表

    这个是正确的,?号匹配最小的范围  。+号范围从1-无限 ,这里就只返回最小值的范围。如果改成*那就是只能匹配到a了,*最小的是0

    >>> re.search('a(d+?)','a123456').group()
    'a1'

    这个结果是错误的
    >>> re.findall('a(d+?)','a123456')
    ['1']

    注意:

    如果按照这个方法匹配?是没有作用的。还是贪婪匹配

    >>> re.findall('a(d+?)b','a12b')
    ['12']

    >>> re.search('a(d+?)b','a122222b').group()
    'a122222b'

    正则查找方法(不在过多介绍使用方法)

    match:re.match(pattern,string,flags=0)

    search:re.search(pattern,string,flags=0)

    search和match下的方法基本一致

          re.search("abcd","abc123").group()#匹配上会返回,没匹配上会报异常。group中可以加参数选择取出哪个组

         

    默认组0,显示所有
    >>> re.search("([1-9]*)([a-z]*)([1-9]*)","123abc456").group(0)
    '123abc456'
    >>> re.search("([1-9]*)([a-z]*)([1-9]*)","123abc456").group(1)
    '123'
    >>> re.search("([1-9]*)([a-z]*)([1-9]*)","123abc456").group(2)
    'abc'
    >>> re.search("([1-9]*)([a-z]*)([1-9]*)","123abc456").group(3)
    '456'
    group组

    flags有很多可选值:

    • re.I(IGNORECASE)忽略大小写,括号内是完整的写法
    • re.M(MULTILINE)多行模式,改变^$的行为
    • re.S(DOTALL)点可以匹配任意字符,包括换行符
    • re.L(LOCALE)做本地化识别的匹配,不推荐使用
    • re.U(UNICODE) 使用w W s S d D使用取决于unicode定义的字符属性。在python3中默认使用该flag
    • re.X(VERBOSE)冗长模式,该模式下pattern字符串可以是多行的,忽略空白字符,并可以添加注释

    替换sub   subn

    sub(pattern, repl, string, count, max=0)

    re.sub()按照从左到右扫描不重叠的匹配串,并用repl替换。repl可以是一个字符串,或者是一个函数(callbale,可调用对象)。如果repl是字符串,则有转义效果;如果是一个函数,那么它参数是match对象,返回一个用于替代的字符串。pattern可以是一个字符串,也可以是一个RE object(即上边的re.compile()返回的对象)。max是替换几次,比如找到5对 这里就可以设置替换几个

    >>> re.sub("a.c","hello","abc 1 abc 2 abc 3")
    'hello 1 hello 2 hello 3'
    >>> re.sub("a.c","hello","abc 1 abc 2 abc 3",2)
    'hello 1 hello 2 abc 3'

    sub 和subn 区别在于subn在返回的时候带替换次数

    >>> re.subn("a.c","hello","abc 1 abc 2 abc 3")
    ('hello 1 hello 2 hello 3', 3)

    re.compile(pattern, flags=0)

    根据包含正则表达式的字符串创建模式对象。

    这个方法的好处就在于如果重复执行查找操作还是用这个编译的比较好

    >>> test = " abc abcd abbc"
    >>> regex = re.compile(r'w*bbw*')    #查找规则
    >>> print regex.findall(test)   #查找的方式更简洁
    ['abbc']

    split:

    这里需要注意的是结果里面为什么包括空值,这里分割的时候每个数字的两侧都进行分割,如果没有就为空

    >>> p=re.compile(r'd+')
    >>> p.split('one1two2three3four4')
    ['one', 'two', 'three', 'four', '']

    finditer:

    可迭代对象

    >>> p=re.compile(r'd+')
    >>> w=p.finditer('12 asd4425 dasd ,121asdasd')
    >>> for match in w:
    ... match.group(),match.span()
    ...
    ('12', (0, 2))        #12 匹配的字符,0,2  是起始和结束位置
    ('4425', (6, 10))
    ('121', (17, 20))

  • 相关阅读:
    LeetCode344
    LeetCode18四数之和扩展N数之和
    LeetCode383赎金信
    2018-2020创业总结
    LeetCode454四数相加
    普通dll项目添加WPF的Window对象
    WPF中RadioButton的数据绑定
    02 C# 文件压缩与解压
    WPF 使用附加属性声明 ICommand
    自定义WPF分页控件
  • 原文地址:https://www.cnblogs.com/menkeyi/p/6734102.html
Copyright © 2020-2023  润新知