正则表达式结合文本文件中的关键字列表以解析为另一个文本文件
Regex in combination with a list of keywords from a textfile to parse into another textfile
我有一个包含很多行的模拟输出,部分内容如下所示:
</GraphicData>
</Connection>
<Connection>
<Name>ES1</Name>
<Type>Port</Type>
<From>Windfarm.Out</From>
<To>BR1.In</To>
<GraphicData>
<Icon>
<Points>
</GraphicData>
</Connection>
<Connection>
<Name>S2</Name>
<Type>Port</Type>
<From>BR1.Out</From>
<To>C1.In</To>
<GraphicData>
<Icon>
<Points>
Name 和 /Name 之间的单词因输出而异。这些名称(此处:ES1 和 S2)存储在文本文件中 (keywords.txt)。
我需要的是一个从列表 (keywords.txt) 中获取关键字的正则表达式。在 (Simulationoutput.txt) 中搜索匹配项,直到 /To> 并将这些匹配项写入另一个文本文件 (finaloutput.txt).
这是我到目前为止所做的
with open("keywords.txt", 'r') as f:
keywords = ast.literal_eval(f.read())
pattern = '|'.join(keywords)
results = []
with open('Simulationoutput.txt', 'r') as f:
for line in f:
matches = re.findall(pattern,line)
if matches:
results.append((line, len(matches)))
results = sorted(results, key=lambda x: x[1], reverse=True)
with open('finaloutput.txt', 'w') as f:
for line, num_matches in results:
f.write('{} {}\n'.format(num_matches, line))
finaloutput.txt 现在看起来像这样:
<Name>ES1</Name>
<Name>S2</Name>
所以代码几乎可以满足我的要求,但输出应该如下所示
<Name>ES1</Name>
<Type>Port</Type>
<From>Hydro.Out</From>
<To>BR1.In</To>
<Name>S2</Name>
<Type>Port</Type>
<From>BR1.Out</From>
<To>C1.In</To>
提前致谢。
虽然我强烈建议您使用 xml.etree.ElementTree
来执行此操作,但您可以使用正则表达式来执行此操作:
import re
keywords = ["ES1", "S2"]
pattern = "|".join([re.escape(key) for key in keywords])
pattern = fr"<Name>(?:{pattern}).*?<\/To>"
with open("Simulationoutput.txt", "r") as f:
matches = re.findall(pattern, f.read(), flags=re.DOTALL)
with open("finaloutput.txt", "w") as f:
f.write("\n\n".join(matches).replace("\n ", "\n"))
使用的正则表达式如下:
<Name>(?:ES1|S2).*?<\/To>
<Name>
:匹配`.
(?:)
: Non-capturing组。
ES1|S2
:匹配 ES1
或 S2
。
.*?
:匹配任意字符,介于零次和无限次之间,越少越好(惰性)。请注意,.
默认情况下不匹配换行符,只是因为设置了 re.DOTALL
标志。
<\/To>
:匹配 </To>
.
我有一个包含很多行的模拟输出,部分内容如下所示:
</GraphicData>
</Connection>
<Connection>
<Name>ES1</Name>
<Type>Port</Type>
<From>Windfarm.Out</From>
<To>BR1.In</To>
<GraphicData>
<Icon>
<Points>
</GraphicData>
</Connection>
<Connection>
<Name>S2</Name>
<Type>Port</Type>
<From>BR1.Out</From>
<To>C1.In</To>
<GraphicData>
<Icon>
<Points>
Name 和 /Name 之间的单词因输出而异。这些名称(此处:ES1 和 S2)存储在文本文件中 (keywords.txt)。
我需要的是一个从列表 (keywords.txt) 中获取关键字的正则表达式。在 (Simulationoutput.txt) 中搜索匹配项,直到 /To> 并将这些匹配项写入另一个文本文件 (finaloutput.txt).
这是我到目前为止所做的
with open("keywords.txt", 'r') as f:
keywords = ast.literal_eval(f.read())
pattern = '|'.join(keywords)
results = []
with open('Simulationoutput.txt', 'r') as f:
for line in f:
matches = re.findall(pattern,line)
if matches:
results.append((line, len(matches)))
results = sorted(results, key=lambda x: x[1], reverse=True)
with open('finaloutput.txt', 'w') as f:
for line, num_matches in results:
f.write('{} {}\n'.format(num_matches, line))
finaloutput.txt 现在看起来像这样:
<Name>ES1</Name>
<Name>S2</Name>
所以代码几乎可以满足我的要求,但输出应该如下所示
<Name>ES1</Name>
<Type>Port</Type>
<From>Hydro.Out</From>
<To>BR1.In</To>
<Name>S2</Name>
<Type>Port</Type>
<From>BR1.Out</From>
<To>C1.In</To>
提前致谢。
虽然我强烈建议您使用 xml.etree.ElementTree
来执行此操作,但您可以使用正则表达式来执行此操作:
import re
keywords = ["ES1", "S2"]
pattern = "|".join([re.escape(key) for key in keywords])
pattern = fr"<Name>(?:{pattern}).*?<\/To>"
with open("Simulationoutput.txt", "r") as f:
matches = re.findall(pattern, f.read(), flags=re.DOTALL)
with open("finaloutput.txt", "w") as f:
f.write("\n\n".join(matches).replace("\n ", "\n"))
使用的正则表达式如下:
<Name>(?:ES1|S2).*?<\/To>
<Name>
:匹配`.(?:)
: Non-capturing组。ES1|S2
:匹配ES1
或S2
。.*?
:匹配任意字符,介于零次和无限次之间,越少越好(惰性)。请注意,.
默认情况下不匹配换行符,只是因为设置了re.DOTALL
标志。<\/To>
:匹配</To>
.