如何避免使用 Python re 库删除文本文件中正则表达式标志之间的文本块?
Posted
技术标签:
【中文标题】如何避免使用 Python re 库删除文本文件中正则表达式标志之间的文本块?【英文标题】:How do I avoid removing blocks of text between Regex flags in my text file using the the Python re library? 【发布时间】:2021-09-18 10:18:19 【问题描述】:我目前正在尝试使用 Python re
库根据我放在这些文件中的唯一标志来剪切文本文件块。但是,如果我在我的文件中包含多个标记块的实例,我会发现所有标记块都集中在一起作为一个大块并被删除。
考虑这个示例文本文件,将其命名为test.txt
:
Do, a deer, a female deer
### mark
Re, a drop of golden sun
### end mark
Mi, a name I call myself
Fa, a long long way to run
### mark
So, a needle pulling thread
La, a note to follow So
Ti, a drink with jam and bread
### end mark
Now that brings us back to Do
我正在使用以下代码来剪切我想要的文本块:
def replace_file_text(path, regex, repl, flags=0):
old_text = ""
with open(path, "r", encoding="utf-8") as f:
old_text = f.read()
new_text = re.sub(regex, repl, old_text, flags=flags)
with open(path, "w", encoding="utf-8") as f:
f.write(new_text)
replace_file_text("test.txt", r"### mark.*### end mark", "", re.DOTALL)
我希望将文本文件转换为:
Do, a deer, a female deer
Mi, a name I call myself
Fa, a long long way to run
Now that brings us back to Do
但我最终得到的是:
Do, a deer, a female deer
Now that brings us back to Do
我知道问题出在哪里,但我不确定如何避免将我的标志实例计数为要删除的文本。
最初,我使用 sed
文本编辑器编写了一个 shell 脚本来剪切这些文本块,并且效果很好:
sed "/### mark/,/### end mark/d" test.txt > new-test.txt
有人可以向我解释为什么后一种方法有效而前一种方法无效吗?有没有人对一种相对干净的方法有任何建议,以避免在 Python 版本中删除我的标志之间的文本?
【问题讨论】:
` r"### mark.*?### end mark"` ? 是的。做到了。谢谢克里斯! 很高兴能帮上忙。此正则表达式中的?
使前面的 .*
nongreedy。正则表达式首先向前看是否匹配### end mark
。如果没有,它会前进一个位置并继续寻找和前进,直到找到那个短语。如果没有non-greedy ?
,.*
会读入字符串中的所有字符,然后回溯以查找该阶段的最后一次出现。 ?
也有其他用途(取决于它的位置)。它将像他的帖子中提到的damonmickelsen
那样运行。
【参考方案1】:
听起来您需要在正则表达式中添加一些特殊字符。比如特殊字符?
导致生成的 RE 匹配前面 RE 的 0 或 1 次重复。 ab?将匹配“a”或“ab”。
目前,如果没有特殊字符,它将是“贪婪的”并匹配模式的第一次和最后一次出现。查看 Python 的“re - Regular expression operation”页面的“特殊字符”部分。
我想你最终会得到这样的结果:
replace_file_text("test.txt", r"(### mark).*(### end mark)?", "", re.DOTALL)
对于正则表达式,我发现反复试验是您找到正确解决方案的方法。它们既复杂又特殊。
【讨论】:
事实证明,我所需要的只是在.*
部分添加一个问号以形成r"### mark.*?### end mark"
。用您使用的术语来说,这基本上使匹配尽可能不贪婪,因此我将小片段相互匹配,而不是整个匹配。不过,感谢您的帮助!以上是关于如何避免使用 Python re 库删除文本文件中正则表达式标志之间的文本块?的主要内容,如果未能解决你的问题,请参考以下文章