比如我们在匹配时常常用到『或』这种情况,举个例子我们需要匹配域名:
>>> re.findall(r'(http|https)://([^/]+)/', 'https://www.baidu.com/index.html')
>>> [('https', 'www.baidu.com')]
因为『或』强制使用到了括号,这样就把http和https也捕获到了,但其实我们可能并不需要前面的schema,此时就需要用到非捕获的匹配组:
>>> re.findall(r'(?:http|https)://([^/]+)/', 'https://www.baidu.com/index.html')
>>> ['www.baidu.com']
在正则匹配时,默认是不重叠的,举例:
>>> re.findall(r'(A.A)', 'ABACA')
>>> ['ABA']
我们其实是想匹配所有A打头和A结尾的三字母串,此时就需要用到重叠匹配了:
>>> re.findall(r'(?=(A.A))', 'ABACA')
>>> ['ABA', 'ACA']
默认正则是贪心的,即匹配的越多越好,举例,贪心是这样的:
>>> re.findall(r'([^ ]+)=(.+)', "name=zhangsan address=shangdi")
>>> [('name', 'zhangsan address=shangdi')]
非贪心是这样的:
>>> re.findall(r'([^ ]+)=(.+?)', "name=zhangsan address=shangdi")
>>> [('name', 'z'), ('address', 's')]
x*和x*?,x+和x+?,加了个问号就不贪心了。
有时候我们需要匹配的字符串要么由引号起起来,要么没有引号,但不接受只有前引号,而没有后引号的情况,此时就需要用到匹配的位置引用:
>>> re.findall(r'([^ ]+)=(\'?)([^\']+)\2', "address=shangdi beijing")
>>> [('address', '', 'shangdi beijing')]
>>> re.findall(r'([^ ]+)=(\'?)([^\']+)\2', "address='shangdi beijing'")
>>> [('address', "'", 'shangdi beijing')]
>>> re.findall(r'([^ ]+)=(\'?)([^\']+)\2', "address='shangdi beijing")
>>> []
比如我们需要对空格做拆分,但是某些特定的空格又不拆分,举个例子:
>>> re.split(r' ', "_name=zhangsan _address=shangdi beijing _age=20")
>>> ['_name=zhangsan', '_address=shangdi', 'beijing', '_age=20']
这个结果肯定不是我们想要的,我们需要拆分的空格后面以下划线开头,因为字段名是下划线打头的,此时我们就需要用到后置条件了:
>>> re.split(r' (?=_)', "_name=zhangsan _address=shangdi beijing _age=20")
>>> ['_name=zhangsan', '_address=shangdi beijing', '_age=20']
前置匹配:(?=re),前置不匹配:(?!re),后置匹配:(?<=re),后置不匹配:(?<!re)