环顾四周和替换的正则表达式

时间:2019-11-30 21:04:30

标签: python regex

我成功地使用Python替换了标签内的文本,例如<tag>some text here</tag>,使用正则表达式([a-zA-Z\s]*),但是将正则表达式简化为(.*)时会失败。参见下面的示例

import re

text = """<tag>
    abc
    def
    ghi
</tag>
"""

print("\nSubstitute the text within the tags , i.e. <tag>...</tag>, with jkl\n")

print("1. Substitution works")
x = re.sub(r'(?<=<tag>\n)([a-zA-Z\s]*)(?=\n</tag>)',r"    jkl",text,re.DOTALL)
print(x)

print("2. Substitution fails")
y = re.sub(r'(?<=<tag>\n)(.*)(?=\n</tag>)',r"    jkl",text,re.DOTALL)
print(y)

输出为

Substitute the text within the tags , i.e. <tag>...</tag>, with jkl

1. Substitution works
<tag>
    jkl
</tag>

2. Substitution fails
<tag>
    abc
    def
    ghi
</tag>

阅读文档后,我仍然不知道为什么。如果有人可以帮助您了解这种Python regex行为,即([a-zA-Z\s]*)为何有效而(.*)失败的原因,我们将不胜感激。

3 个答案:

答案 0 :(得分:2)

每个人似乎都错过了这一点:re.sub的文档将参数显示为:

re.sub(pattern, repl, string, count=0, flags=0)

也就是说,第四个参数是要执行的替换次数的计数,而不是要使用的标志。您说的是re.DOTALL,但它被解释为count参数。您只需要说flags=re.DOTALL即可确保使用了正确的标志,以使.字符与换行符匹配:

y = re.sub(r'(?<=<tag>\n)(.*)(?=\n</tag>)',r"    jkl",text, flags=re.DOTALL)

您应该更新所有代码,以在flags=之前添加re.DOTALL

import re

text = """<tag>
    abc
    def
    ghi
</tag>
"""
print("2. Substitution works!")
y = re.sub(r'(?<=<tag>\n)(.*)(?=\n</tag>)',r"    jkl",text, flags=re.DOTALL)
print(y)

打印:

2. Substitution works!
<tag>
    jkl
</tag>

答案 1 :(得分:0)

第一个\s与任何空格字符(即换行符)匹配。

.与行终止符不匹配。

https://regex101.com/是非常有用的资源。

答案 2 :(得分:0)

find explanation here

请在regex101.com所附的屏幕截图中找到答案