gpt4 book ai didi

Python - 错误 : look-behind requires fixed-width pattern

转载 作者:行者123 更新时间:2023-12-04 20:41:40 28 4
gpt4 key购买 nike

我有一个看起来像的字符串:

phrase = '5 hampshire road bradford on avon avon dinas powys powys north somerset hampshire avon'

我想返回一个删除了某些单词的新字符串,前提是它们前面没有某些其他单词。

例如,我要删除的词是:
c_out = ["avon", "powys", "somerset","hampshire"]

只有当他们不遵循:
c_except = ["on\s","dinas\s"]

注意: c_out 中可能有多个单词实例,以及 c_except 中的多个单词实例.

我个人尝试过 'on\s' :
phrase = '5 hampshire road bradford on avon avon dinas powys powys north somerset hampshire avon'

regexp1 = re.compile(r'(?<!on\s)(avon|powys|somerset|hampshire)')
print("1st Result: ", regexp1.sub('', phrase))
1st Result: '5 road bradford on avon avon dinas north'

这正确地忽略了第一个 'avon' ,因为它前面是 'on\s' ,它正确地删除了第三个 'avon' , 但是 它忽略第二个 'avon' (它不会删除)。

同理,对于 'dinas\s' :
phrase = '5 hampshire road bradford on avon avon dinas powys powys north somerset hampshire avon'

regexp2 = re.compile(r'(?<!dinas\s)(avon|powys|somerset|hampshire)')
print("2nd Result: ", regexp2.sub('', phrase))
2nd Result: '5 road bradford on dinas powys north '

这正确地忽略了第一个 'powys'并删除第二个(注意 '... powys north' 之间的双空格。

我尝试通过执行以下操作来组合这两个表达式:
regexp3 = re.compile(r'((?!on\s)|(?!dinas\s))(avon|powys|somerset|hampshire)')
print("3rd Result: ", regexp3.sub('', phrase))
3rd Result: 5 road bradford on dinas north

这错误地删除了每个单词,并完全忽略了 'on\s''dinas\s' .

然后我尝试:
regexp4 = re.compile(r'(?<!on\s|dinas\s)(avon|powys|somerset|hampshire)')
print("4th Result: ", regexp4.sub('', phrase))

并得到:
error: look-behind requires fixed-width pattern

我想结束:
Result: '5  road bradford on avon dinas powys  north     '

我看过:

Why is this not a fixed width pattern?
Python Regex Engine - "look-behind requires fixed-width pattern" Error
regex: string with optional parts

但无济于事。

我究竟做错了什么?

来自评论:
regexp5 = re.compile(r'(?<!on\s)(?<!dinas\s)(avon|powys|somerset|hampshire)')
print("5th Result: ", regexp5.sub('', phrase))
5th Result: 5 road bradford on avon avon dinas powys north

这再次错过了第二个雅芳。

最佳答案

这里有两种方法可以解决这个问题:
链式后视
将基于交替的lookbehind 转换为几个negative lookbehind,因为它们之间的逻辑关系将相同(AND 的逻辑关系):

import re
phrase = '5 hampshire road bradford on avon avon dinas powys powys north somerset hampshire avon'
c_except = [r"on\s",r"dinas\s"]
c_out = ["avon", "powys", "somerset","hampshire"]
rx = r"(?<!\b{0})({1})".format(r")(?<!\b".join(c_except), "|".join(c_out))
print(re.sub(rx, "", phrase))
this Python demo .
捕获方法
捕获您需要保留的内容并仅匹配您需要删除的内容,然后使用 \1恢复组 1 值的反向引用:
import re
phrase = '5 hampshire road bradford on avon avon dinas powys powys north somerset hampshire avon'
c_except = [r"on\s+",r"dinas\s+"]
c_out = ["avon", "powys", "somerset","hampshire"]
rx = r"(\b(?:{0})(?:{1}))|(?:{1})".format(r"|".join(c_except), "|".join(c_out))
print(re.sub(rx, r"\1", phrase))
another Python demo .
请注意,这种方法是有利的,因为您可以在 c_except 中使用可变宽度图案。 .
正则表达式看起来像
(\b(?:on\s+|dinas\s+)(?:avon|powys|somerset|hampshire))|(?:avon|powys|somerset|hampshire)
它将匹配 ondinas由于 \b整个词词边界,然后是您需要删除的任何术语,并且由于该部分包含在捕获组中,因此您可以使用 \1 来引用捕获。反向引用。在所有其他上下文中, c_out条款将被删除 |(?:avon|powys|somerset|hampshire)图案。
注意: \1替换将在 Python 3.5+ 中工作。对于旧版本和 Python 2.x,您需要将其替换为 lambda:
re.sub(rx, lambda m: m.group(1) if m.group(1) else "", phrase)

关于Python - 错误 : look-behind requires fixed-width pattern,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45479563/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com