我想将文件的内容打印到终端,并在此过程中突出显示列表中找到的任何单词而不修改原始文件。这是一个尚未运行的代码示例:
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's{0,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 吃人类和非人类动物。在光线不足的地区狗和 hedgehogs 被任何富裕的 grue 视为美味佳肴。然而, Dogs 可以通过在音阶中吠叫来吓跑 grue 。另一方面, hedgehog 必须简单地让自己屈服于成为适合 grue 国王的热狗的命运。
如何阻止其他替换丢失?
答案 0 :(得分:5)
您可以将正则表达式修改为以下内容:
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?
答案 1 :(得分:4)
提供的正则表达式是正确的,但for循环是你出错的地方。
result = re.sub(regex, subst, file_contents)
此行将regex
替换为subst
中的file_content
。
在第二次迭代中,它再次在file_content
中进行替换,您希望在result
上进行替换
如何纠正
result = file_contents
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
答案 2 :(得分: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's{0,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's{0,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()