替换 RegEx 中的精确分组部分 Python

Replace An Exact Grouped Part in RegEx Python

我有一个模板,我需要使用 Python 中的 Regex 替换其中的一部分。这是我的模板:(注意两条评论之间至少要换行)

hello
how's everything

<!--POSTS:START-->
some text
<!--POSTS:END-->

Some code here

我想替换 Python 中 <!--POSTS:START--><!--POSTS:END--> 之间的所有内容。所以我制作了 <!--POSTS:START-->\n([^;]*)\n<!--POSTS:END--> 模式,但它也包括 <!--POSTS:START--><!--POSTS:END-->

这是我想要的:

re.sub('...', 'foo', message)

# expected result:
hello
how's everything

<!--POSTS:START-->
foo
<!--POSTS:END-->

Some code here

谢谢。

您可以为开始和结束标记使用捕获组,并在目标替换字符串中将它们引用为 \1、\2 等。

如果文本多次出现 <!--POSTS:START-->...<!--POSTS:END-->,则带有 .*? 的正则表达式将替换这些组中的每一个。如果'?删除了正则表达式,然后它将删除从第一组开始到最后一组结束的所有文本。

试试这个:

import re

s = '''
hello
how's everything

<!--POSTS:START-->
some text
<!--POSTS:END-->

Some code here
'''

# for multi-line matching need extra flags in the regexp
s = re.sub(r'(<!--POSTS:START-->\n).*?(\n<!--POSTS:END-->)', r'foo', s, flags=re.DOTALL)

# this inlines the DOTALL flag in the regexp for same result
# s = re.sub(r'(?s)(<!--POSTS:START-->\n).*?(\n<!--POSTS:END-->)', r'foo', s)

print(s)

输出:

hello
how's everything

<!--POSTS:START-->
foo
<!--POSTS:END-->

Some code here

您可以使用以下内容:

import re

new_content = re.sub(
    r'(<!--POSTS:START-->\n).*?(?=\n<!--POSTS:END-->)', r"foo",
    content, flags=re.DOTALL)

DOTALL 标志:制作“.”特殊字符完全匹配任何字符,包括换行符。

我正在使用两个东西来做你想做的事

  • Group lookahead "?=":断言可以在此处匹配给定的子模式,而无需消耗字符
  • 非贪婪匹配模式 (*?)。这将以非贪婪模式匹配。这样我们就可以得到所有的模式separatly

由于我们使用的是lookahead,\n<!--POSTS:END-->不会被消耗所以我只需要保留第一组并在匹配之间重写内容。这就是为什么我使用 foo 而不是 foo

如果您只需要修改第一个匹配项,您可以使用 count=1

re.sub(..., count=1)

你可以在这两行之间添加任何内容,它会按预期工作

检查这个https://docs.python.org/3/library/re.html

import re

pattern = r"(<!--POSTS:START-->\n).*(\n<!--POSTS:END-->)"
string = """hello
how's everything

<!--POSTS:START-->
some text
<!--POSTS:END-->

Some code here"""
result = re.sub(pattern, r"\g<1>foo\g<2>", string)
print(result)

结果:

hello
how's everything

<!--POSTS:START-->
foo
<!--POSTS:END-->

Some code here