Python 正则表达式 (?=...) 和 (?<=...) 符号

Python 正则表达式

引言

今天遇到了一个比较棘手的问题,于是终于打算要对正则表达式中的 (?=...)(?<=...) 符号动手了。

正文

(?=...) 表示当 匹配时,匹配成功,但不消耗字符串中的任何字符。这个叫做 前视断言 (lookahead assertion)。比如, Isaac (?=Asimov) 将会匹配 Isaac ,仅当其后紧跟 Asimov

Python 正则表达式 (…) 符号 一文中,我们说明了为什么要使用 () 符号以及 ... 符号的含义。事实上,上述的 (?=...)(?<=...) 中的 ... 符号可以被替换为任意的符号,这里为了方便说明问题,我们将 ... 符号替换为 \t 符号。

示例1

import re

str1 = 'abc\tdefghi\txyz'
print(re.search('(?=\t)', str1))
"""
result:
<re.Match object; span=(3, 3), match=''>
"""

可以看到,它匹配到了索引值为 3\t 字符,但是由于它是前视断言,即向前搜索,而我们的匹配项中 (?=\t) 之前并没有任何字符,因此什么也没有匹配到。

示例2

我们对示例 1 中的匹配内容稍作更改。

import re

str1 = 'abc\tdefghi\txyz'
print(re.search('abc(?=\t)', str1))
"""
result:
<re.Match object; span=(0, 3), match='abc'>
"""

此时可以看到,匹配到了字符串 abc

示例3

(?<=...) 表示如果 ... 的匹配内容出现在当前位置的左侧,则匹配。这叫做 肯定型后视断言 (positive lookbehind assertion)(?<=abc)def 将会在 abcdef 中找到一个匹配,因为后视会回退 3 个字符并检查内部表达式是否匹配。内部表达式(匹配的内容)必须是固定长度的,意思就是 abca|b 是允许的,但是 a*a{3,4} 不可以。注意,以肯定型后视断言开头的正则表达式,匹配项一般不会位于搜索字符串的开头。

上面的解释比较抽象,那么具体是什么意思呢?我们看一个例子。

import re

str1 = 'abc\tdefghi\txyz'
print(re.search('(?<=\t)def', str1))
"""
result:
<re.Match object; span=(4, 7), match='def'>
"""

程序先找到 def 字符串,然后再回退一个字符查看 def 前面的字符是否是 \t 字符,如果是,那么就匹配 def 字符串。

示例4

如果我们想要匹配两个 \t 字符中间的部分怎么办呢?

import re

str1 = 'abc\tdefghi\txyz'
print(re.search('\t(.*)\t', str1))
"""
result:
<re.Match object; span=(3, 11), match='\tdefghi\t'>
"""

可以看到,此时,结果中包含了两端的 \t 字符,但是我们不想要它包含 \t 字符。为了实现这一目标,我们可以采用刚才我们提到的后视和前视。

import re

str1 = 'abc\tdefghi\txyz'
print(re.search('(?<=\t).*(?=\t)', str1))
"""
result:
<re.Match object; span=(4, 10), match='defghi'>
"""

可以看到我们匹配到了两个 \t 字符中间的字符串,但是上述写法并不严谨,为了严谨,我们可以使用:

import re

str1 = 'abc\tdefghi\txyz'
print(re.search('(?<=\t)(.*)(?=\t)', str1))
"""
result:
<re.Match object; span=(4, 10), match='defghi'>
"""

如果大家觉得有用,就请点个赞吧~

相关推荐

  1. Python 表达式 *, + ? 符号

    2024-05-12 09:04:03       38 阅读
  2. Python 表达式 (?=...) (?<=...) 符号

    2024-05-12 09:04:03       30 阅读
  3. Python 表达式 re . 符号

    2024-05-12 09:04:03       39 阅读
  4. Python表达式

    2024-05-12 09:04:03       48 阅读
  5. Python 表达式

    2024-05-12 09:04:03       40 阅读
  6. python表达式

    2024-05-12 09:04:03       41 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-05-12 09:04:03       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-05-12 09:04:03       100 阅读
  3. 在Django里面运行非项目文件

    2024-05-12 09:04:03       82 阅读
  4. Python语言-面向对象

    2024-05-12 09:04:03       91 阅读

热门阅读

  1. Electron axios token失效刷新token

    2024-05-12 09:04:03       36 阅读
  2. 2024-05-11 问AI:在深度学习中,学习率是什么

    2024-05-12 09:04:03       35 阅读
  3. Python 实战之量化交易

    2024-05-12 09:04:03       32 阅读
  4. CentOS常见命令

    2024-05-12 09:04:03       28 阅读
  5. CentOS常见的命令及其高质量应用

    2024-05-12 09:04:03       26 阅读
  6. P1098 [NOIP2007 提高组] 字符串的展开

    2024-05-12 09:04:03       30 阅读
  7. Unity 浮点数的精度问题

    2024-05-12 09:04:03       33 阅读
  8. 游戏行业该如何选择适合的服务器?

    2024-05-12 09:04:03       37 阅读
  9. 向量检索和关键字检索的区别?

    2024-05-12 09:04:03       31 阅读
  10. 使用 Spring Boot 构建 RESTful API 的最佳实践

    2024-05-12 09:04:03       30 阅读
  11. 三方库的调用方法

    2024-05-12 09:04:03       26 阅读