首页 > 解决方案 > 用注释替换注释,根据注释行数阻塞注释,python中用正则表达式

问题描述

我想转换以下文本:

some text
% comment line 1
% comment line 2
% comment line 3
some more text

进入

some text
"""
comment line 1
comment line 2
comment line 3
"""
some more text

并且在同一个文件中,当只有一行注释时,我希望它从

some text
% a single commented line
some more text

some text 
# a single commented line
some more text

所以,当这两个案例在同一个文件中时,我想从:

some text
% comment line 1
% comment line 2
% comment line 3
some more text
some text
% a single commented line
some more text

some text
"""
comment line 1
comment line 2
comment line 3
"""
some more text
some text 
# a single commented line
some more text

到目前为止,我尝试过的第二种情况是:

re.sub(r'(\A|\r|\n|\r\n|^)% ', r'\1# ',  'some text \n% a single comment line\nsome more text')

但是当评论超过一行时,它也会替换%为。#

至于第二种情况,我失败了:

re.sub(r'(\A|\r|\n|\r\n|^)(% )(.*)(?:\n^\t.*)*', r'"""\3"""',  'some text \n% comment line1\n% comment line 2\n% comment line 3\nsome more text') 

它在每一行重复,"""并与仅注释一行的情况相冲突。

有没有办法计算找到正则表达式的连续行并相应地更改模式?

在此先感谢您的帮助!

标签: regexpython-3.x

解决方案


虽然这可能使用正则表达式是可能的,但我认为没有正则表达式会容易得多。例如,您可以使用itertools.groupby来检测连续注释行组,只需使用str.startswith来检查一行是否是注释。

text = """some text
% comment line 1
% comment line 2
% comment line 3
some more text
some text
% a single commented line
some more text"""

import itertools
for k, grp in itertools.groupby(text.splitlines(), key=lambda s: s.startswith("%")):
    if not k:
        for s in grp:
            print(s)
    else:
        grp = list(grp)
        if len(grp) == 1:
            print("# " + grp[0].lstrip("% "))
        else:
            print('"""')
            for s in grp:
                print(s.lstrip("% "))
            print('"""')

这只是打印结果文本,但您当然也可以将它收集到某个字符串变量中并返回它。如果注释也可以从一行的中间开始,您可以在if not k块中检查这一点。在这里re.sub,使用例如区分%和是有意义的\%


推荐阅读