在 Python 中使用正则表达式查找和替换文件中的单词列表
Posted
技术标签:
【中文标题】在 Python 中使用正则表达式查找和替换文件中的单词列表【英文标题】:Finding and substituting a list of words in a file using regex in Python 【发布时间】:2015-01-05 10:11:00 【问题描述】:我想将文件的内容打印到终端,并在此过程中突出显示在列表中找到的任何单词,而不修改原始文件。以下是尚未生效的代码示例:
def highlight_story(self):
"""Print a line from a file and highlight words in a list."""
the_file = open(self.filename, 'r')
file_contents = the_file.read()
for word in highlight_terms:
regex = re.compile(
r'\b' # Word boundary.
+ word # Each item in the list.
+ r's0,1', # One optional 's' at the end.
flags=re.IGNORECASE | re.VERBOSE)
subst = '\033[1;41m' + r'\g<0>' + '\033[0m'
result = re.sub(regex, subst, file_contents)
print result
the_file.close()
highlight_terms = [
'dog',
'hedgehog',
'grue'
]
事实上,只有列表中的最后一项,无论它是什么或列表有多长,都会被突出显示。我假设每次替换都被执行,然后在下一次迭代开始时“忘记”。它看起来像这样:
Grues 已知会吃人类和非人类动物。在光线不足的地区,任何富裕的grue都认为狗和刺猬是美味佳肴。然而,狗可以通过在音阶中吠叫来吓唬 grue。另一方面,刺猬必须接受自己成为适合 grue 国王的热狗的命运。
但它应该是这样的:
Grues 已知会吃人类和非人类动物。在光线不足的地区,dogs 和 hedgehogs 被任何富裕的 grue 视为美味佳肴。 Dogs 可以吓跑 grue,但是,通过在音阶中吠叫。另一方面,hedgehog 必须接受自己成为适合 grue 国王的热狗的命运。
我怎样才能阻止其他替换丢失?
【问题讨论】:
【参考方案1】:您可以将您的正则表达式修改为以下内容:
regex = re.compile(r'\b('+'|'.join(highlight_terms)+r')s?', flags=re.IGNORECASE | re.VERBOSE) # note the ? instead of 0, 1. It has the same effect
那么,您将不需要for
循环。
此代码获取单词列表,然后将它们与|
连接在一起。所以如果你的清单是这样的:
a = ['cat', 'dog', 'mouse'];
正则表达式是:
\b(cat|dog|mouse)s?
【讨论】:
@ChristopherPerry,没问题。很高兴我能帮忙【参考方案2】:您需要每次通过循环将file_contents
重新分配给被替换的字符串,重新分配file_contents
不会改变文件中的内容:
def highlight_story(self):
"""Print a line from a file and highlight words in a list."""
the_file = open(self.filename, 'r')
file_contents = the_file.read()
output = ""
for word in highlight_terms:
regex = re.compile(
r'\b' # Word boundary.
+ word # Each item in the list.
+ r's0,1', # One optional 's' at the end.
flags=re.IGNORECASE | re.VERBOSE)
subst = '\033[1;41m' + r'\g<0>' + '\033[0m'
file_contents = re.sub(regex, subst, file_contents) # reassign to updatedvalue
print file_contents
the_file.close()
另外使用 with 打开文件是一种更好的方法,您可以在循环外复制字符串并在内部更新:
def highlight_story(self):
"""Print a line from a file and highlight words in a list."""
with open(self.filename) as the_file:
file_contents = the_file.read()
output = file_contents # copy
for word in highlight_terms:
regex = re.compile(
r'\b' # Word boundary.
+ word # Each item in the list.
+ r's0,1', # One optional 's' at the end.
flags=re.IGNORECASE | re.VERBOSE)
subst = '\033[1;41m' + r'\g<0>' + '\033[0m'
output = re.sub(regex, subst, output) # update copy
print output
the_file.close()
【讨论】:
【参考方案3】:提供的正则表达式是正确的,但 for 循环是你出错的地方。
result = re.sub(regex, subst, file_contents)
此行将regex
中的subst
替换为file_content
。
在第二次迭代中,它再次在 file_content
中进行替换,正如您打算在 result
上进行的那样
如何纠正
结果 = 文件内容
for word in highlight_terms:
regex = re.compile(
r'\b' # Word boundary.
+ word # Each item in the list.
+ r's?\b', # One optional 's' at the end.
flags=re.IGNORECASE | re.VERBOSE)
print regex.pattern
subst = '\033[1;41m' + r'\g<0>' + '\033[0m'
result = re.sub(regex, subst, result) #change made here
print result
【讨论】:
以上是关于在 Python 中使用正则表达式查找和替换文件中的单词列表的主要内容,如果未能解决你的问题,请参考以下文章