Замените комментарии комментариями и блокируйте комментарии в соответствии с количеством прокомментированных строк регулярным выражением в python - PullRequest
1 голос
/ 27 июня 2019

Я хотел бы преобразовать следующий текст:

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') 

, который повторяет """ в каждой строке и конфликтует со случаем, когда комментируется только одна строка.

Есть ли способ подсчитать последовательные строки, в которых найдено регулярное выражение, и соответственно изменить шаблон?

Заранее спасибо за помощь!

Ответы [ 2 ]

2 голосов
/ 27 июня 2019

Хотя это возможно с помощью регулярного выражения, я думаю, что без него гораздо проще.Например, вы можете использовать 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, например, чтобы различать % и \%.

1 голос
/ 27 июня 2019

Прямо:

with open('input.txt') as f:
    comments = []

    def reformat_comments(comments):
        if len(comments) == 1:
            comments_str = '#' + comments[0] + '\n'
        else:
            comments_str = '"""\n{}\n"""\n'.format('\n'.join(comments))
        return comments_str

    for line in f:
        line = line.strip()
        if line.startswith('% '):
            comments.append(line.lstrip('%'))
        elif comments:
            print(reformat_comments(comments) + line)
            comments = []
        else:
            print(line)
    if comments: print(reformat_comments(comments))

Пример вывода:

some text
"""
 comment line 1
 comment line 2
 comment line 3
"""
some more text
some text
# a single commented line
some more text
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...