高阶正则表达式

非捕获的匹配组(Non-capturing group)

比如我们在匹配时常常用到『或』这种情况,举个例子我们需要匹配域名:

>>> 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']

重叠匹配(overlapping-matching)

在正则匹配时,默认是不重叠的,举例:

>>> 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)

发表于 2023年10月17日 22:25   评论:0   阅读:4442  



回到顶部

首页 | 关于我 | 关于本站 | 站内留言 | rss
python logo   django logo   tornado logo