带有负前瞻和负后瞻的正则表达式来检查我的匹配是否不在 [[ 和 ]] 之间

问题描述 投票:0回答:1

我正在尝试编写一个Python脚本,它可以在给定的md文件中替换[[和]]之间给定关键字的出现。

它将在同一个文件上使用多次,所以我不想以例如 FOO 变成 [[FOO]],然后 [[[[FOO]]]] 等结束。

所以我不希望 FOO 与 [[ 和 ]] 一起循环。

我想出的最接近的版本是这样的:

(?<!\[\[)\b(FOO)\b(?!\]\])

我的测试列表的状态是:

Should     match : lorem ipsum FOO dolor              ==> OK
Should NOT match : lorem ipsum [[FOO]]  dolor         ==> OK
Should NOT match : lorem [[ipsum FOO dolor]] sit amet ==> Not OK
Should NOT match : lorem [[ipsumFOOsolor]] sit amet   ==> OK
Should NOT match : [[lorem]]  [[ipsum-FOO&dolor-sit.pdf#page=130]] ==> Not OK

作为参考,我想在这个 python 代码片段中使用这个正则表达式:

    for term in term_list:
        pattern = r'(?<!\[\[)\b(' + re.escape(term) + r')\b(?!\]\])'
        file_content = re.sub(pattern, r'[[\1]]', file_content)

我需要的正则表达式是什么? 这种方法有什么问题吗?

谢谢!

python regex regex-negation regex-replace
1个回答
0
投票

在不考虑嵌套

[[..[[..]]..]]
的情况下,您可能会做的就是将
[[...]]
部分移开并捕获您想要保留在组中的内容。

然后在替换中使用该组,并保留仅匹配(不在组中)的部分不变。

import re

pattern = r"\[\[(?:(?!\[\[|]]).)*\]\]|\b(FOO)\b"

s = ("lorem ipsum FOO dolor\n"
            "Should NOT match : lorem ipsum [[FOO]]  dolor\n"
            "Should NOT match : lorem [[ipsum FOO dolor]] sit amet\n"
            "Should NOT match : lorem [[ipsumFOOsolor]] sit amet\n"
            "Should NOT match : [[lorem]]  [[ipsum-FOO&dolor-sit.pdf#page=130]]")

result = re.sub(pattern, lambda x: f"[[{x.group(1)}]]" if x.group(1) else x.group(), s)
print(result)

输出

lorem ipsum [[FOO]] dolor
Should NOT match : lorem ipsum [[FOO]]  dolor
Should NOT match : lorem [[ipsum FOO dolor]] sit amet
Should NOT match : lorem [[ipsumFOOsolor]] sit amet
Should NOT match : [[lorem]]  [[ipsum-FOO&dolor-sit.pdf#page=130]]
© www.soinside.com 2019 - 2024. All rights reserved.