regex 将捕获组替换为行号(sed?awk?python?)

jogvjijk  于 2023-08-08  发布在  Python
关注(0)|答案(1)|浏览(82)

我有源代码,我想在其中插入filename:linumber到各种日志语句中,例如:

logger.e("", "an error happened");

字符串
第一个字符串文字需要替换。字符串文本不能为空。如果我正在编辑一个已经运行了替换程序的文件,那么该行可能是:

logger.e("filename:123", "an error happened, this is the line number the last time I edited the file.")


计划是创建一个文本处理器作为构建管道的一部分,它对日志语句进行搜索和替换,并插入filename:linumber。我最初计划使用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

uqzxnwby

uqzxnwby1#

你的总体接近。在您的情况下,最好将除您想要替换的内容之外的所有内容都捕获到组中。
所以你可以使用(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)

字符串
在线演示here

相关问题