当前位置: 首页 > 面试题库 >

带有反向引用的不可能的回溯

蒋弘致
2023-03-14
问题内容

据我了解

(.)(?<!\1)

不应该匹配。实际上,phppreg_replace甚至拒绝编译它,而ruby的也是如此gsubpythonre模块似乎有不同的看法:

import re
test = 'xAAAAAyBBBBz'
print (re.sub(r'(.)(?<!\1)', r'(\g<0>)', test))

结果:

(x)AAAA(A)(y)BBB(B)(z)

任何人都可以对此行为提供合理的解释吗?

更新资料
这种行为似乎是限制了在re模块。替代regex模块似乎可以正确处理断言中的组:

import regex

test = 'xAAAAAyBBBBz'

print (regex.sub(r'(.)(?<!\1)', r'(\g<0>)', test))
## xAAAAAyBBBBz

print (regex.sub(r'(.)(.)(?<!\1)', r'(\g<0>)', test))
## (xA)AAA(Ay)BBB(Bz)

请注意,与有所不同pcre,regex它还允许可变宽度的查找:

print (regex.sub(r'(.)(?<![A-Z]+)', r'(\g<0>)', test))
## (x)AAAAA(y)BBBB(z)

最终,regex将被包含在标准库中,如PEP 411中所述。


问题答案:

这看起来确实像是Pythonre模块中的一个限制(我从Microsoft的支持电话中学到的一种“错误”的好说法)。

我猜想这与以下事实有关:Python不支持可变长度的后向断言,但是它不够聪明,无法确定\1始终是固定长度的。我不能说为什么在编译正则表达式时不抱怨这一点。

很有趣:

>>> print (re.sub(r'.(?<!\0)', r'(\g<0>)', test))
(x)(A)(A)(A)(A)(A)(y)(B)(B)(B)(B)(z)
>>>
>>> re.compile(r'(.*)(?<!\1)') # This should trigger an error but doesn't!
<_sre.SRE_Pattern object at 0x00000000026A89C0>

因此最好不要在Python的后置断言中使用反向引用。正向后看并不会好得多(它在这里也像正向前向相匹配):

>>> print (re.sub(r'(.)(?<=\1)', r'(\g<0>)', test))
x(A)(A)(A)(A)Ay(B)(B)(B)Bz

而且我什至无法猜测这里发生了什么:

>>> print (re.sub(r'(.+)(?<=\1)', r'(\g<0>)', test))
x(AA)(A)(A)Ay(BB)(B)Bz


 类似资料:
  • 最近有了这两个DTO,我犯了这个错误 MappingJackson2HttpMessageConverter: 163-无法评估类型[简单类型,类seml.dto.PoiDto]的Jackson反序列化:java.lang.IllegalArgumentException:无法处理托管/反向引用'default引用':反向引用类型(java.util.设置)与托管类型(seml.dto.Conce

  • 问题内容: 我有以“键-键”格式而不是“键-值”格式组织的数据。这就像一个HashMap,但是我将需要在两个方向上进行O(1)查找。这种数据结构是否有名称,Java的标准库中是否包含类似的名称?(或者Apache Commons?) 我可以编写自己的类,该类基本上使用两个镜像的Map,但我不想重蹈覆辙(如果已经存在,但我只是没有在寻找正确的术语)。 问题答案: Java API中没有此类。您想要的

  • 我实现了一个这样的树 但是在 PyCharm 中,我得到有解决方法吗?

  • 问题内容: 这可能是一个愚蠢的问题,但是这里有: 是否可以制作一个动态表,使其能够包含具有可变列数和自定义列名的行? 我浏览了EAV建模,但看起来很沉重。一个真实的例子可能是这样的: 假设我有一个客户登记册。但是每个客户可能要输入不同的信息。并且取决于您要输入的内容,它应该反映在数据库中。(即每个客户都有不同的列) 这是不可能/可能吗? 更新: 标准方法(即, 具有一个包含所有需要的列的表,并且仅

  • 问题内容: 我正在尝试使用AJAX将查询发送到Google图书并将结果显示在我的网站上。我正在使用JQuery发送请求并处理响应,如下所示: 当前,如果收到响应,我只是具有警告“成功”的脚本。如果我使用脚本将查询发送到本地页面进行测试,则效果很好。但是,当我按照开发人员API页面上的指示将网址设置为上面列出的Google网址时,我再也看不到该警报。根据Firebug的说法,我会收到应有的响应,并且

  • 我是新来的Spring Security,并试图开发Spring Boot应用程序与谷歌登录使用OAuth2下运行的主机名: 8080。这个程序是背后的Apache反向代理服务器https://url.com. Spring启动版本2.1。0 Spring Security版本5.1.1 build.gradle: 应用yml: Spring Security配置: 我请求https://url.