我有源代码,我想将文件名:行号插入到各种日志语句中,例如:
logger.e("", "an error happened");
第一个字符串文字需要替换。字符串文字可能不为空。如果我正在编辑一个已经运行了替换的文件,则该行可能是:
logger.e("filename:123", "an error happened, this is the line number the last time I edited the file.")
计划是创建一个文本处理器作为我的构建管道的一部分,它对日志语句进行搜索和替换并插入文件名:行号。我原本计划使用 awk,但在努力让它发挥作用后,我会满足于使用任何合适的工具。
我创建了一个正则表达式,旨在捕获要在捕获组中替换的文本:
logger\.[tdiwe]\("(.*?)"
这应该(我认为)匹配以“logger”开头的文本,然后是一个点,然后是 t、d、i、w 或 e 中的任何一个(trace/debug/info/warn/error),然后是左括号,然后双引号,然后零个或多个字符,然后是双引号。我相信,但不是 100% 确定,正则表达式的
"(.*?)"
部分将第一组双引号之间的字符放入捕获组中。
然而,在各种工具中研究这一点后,似乎提取捕获组很简单,但替换它们却不是。
我确实得到了一些Python代码来做我想做的事情,但这似乎有点过分了,我已经花了足够的时间来解决这个问题,我希望有人向我展示更简单的方法。
with open(infilename) as infile:
with open(outfilename, "w") as outfile:
linenumber = 1
for line in infile:
rslt = re.search(r'logger\.[tdiwe]\("([^"]*)', line)
if rslt:
outfile.write(line[:rslt.span(1)[0]] + f"filename:{str(linenumber)}" + line[rslt.span(1)[1]:])
else:
outfile.write(line)
linenumber += 1
您的总体方法很接近。但在您的情况下,最好将除您想要替换的内容之外的所有内容都捕获到组中。
因此您可以使用
(logger\.[tdiwe]\(")[^"]*
和替换字符串 \1filename:123
。
您的代码将如下所示:
import re
infilename = 'myinputfile'
outfilename = 'myoutputfile'
myregex = re.compile(r'(logger\.[tdiwe]\(")[^"]*')
with open(infilename) as infile:
lines = infile.readlines()
for line_number, line in enumerate(lines):
lines[line_number] = myregex.sub(r'\1' + f'{infilename}:{str(line_number+1)}', line)
with open(outfilename, "w") as outfile:
outfile.writelines(lines)
在线演示这里。