Удаление однострочных комментариев: Python для начинающих

Удаление однострочных комментариев: Python для начинающих

8 марта 2023 г.

Как удалить однострочные комментарии…

Недавно я работал над своим студенческим проектом (пирамидой), который был похож на разметку, и хотел добавить к нему поддержку комментариев. Поскольку комментарии очень полезны для документации, и я нахожу их благословением, я хотел убедиться, что мой проект также имеет эту функцию.

Итак, я решил написать код для их разбора. Я потерпел неудачу в довольно многих своих подходах, но затем мне это удалось, и я хотел поделиться радостью от успешного написания кода для удаления комментариев.

Я хотел реализовать комментарии, начинающиеся с «#». После нескольких неудач я установил для себя два основных правила:

* Если первым символом строки является "#", удалите всю строку.

* Если количество апострофов или кавычек перед символом «#» четное, удалите все символы от символа «#» до конца строки.

Установив эти два правила, я теперь определил для себя направление движения. Я проверял свой код на следующем тексте:

test.txt

#this is a comment
this is not a "#comment"
this is a # comment and #this follows in
"#this is not a comment" but #this is
"# not a comment"

Выполнить первое правило так же просто, как:

with open("test.txt","r") as file:
    text = file.read()

lines = text.strip().split('n')    # splitting lines 
comments = []   # to store commented lines for removal
for line in lines:
    if(line[0] == "#"):
        comments.append(line)

for line in comments:
    lines.remove(line)

При этом удаляются все строки, начинающиеся с «#». Теперь переходим ко второму правилу, реализовать которое было довольно интересно. Вот как это происходит:

* Ведите список с индексами апострофов, кавычек и символов решетки для каждой строки. И отдельный список индексов комментариев для каждой строки.

* Подсчитайте количество апострофов и кавычек для каждого хеша, индекс которого меньше, чем у самого хеша. Здесь возникают два случая:

* Если количество апострофов и кавычек четное, то добавить в список комментариев индекс решётки; не проверяйте оставшиеся символы решетки.

* Если количество апострофов или кавычек нечетное, проверьте наличие следующего хэша в строке. Если в строке больше нет хэшей, добавьте 0 в качестве индекса в список комментариев.

* Теперь у нас есть индексы начала комментариев в каждой строке, а строки, в которых нет комментария, имеют для них индекс 0. Поэтому теперь мы перейдем к удалению текста, начиная с индекса хеша и до конца строки, чтобы удалить комментарий.

* И ничего не сделает, если индекс равен 0, так как в строке нет комментария.

### Вот полная реализация правила, добавленного к приведенному выше коду:

lines = text.strip().split('n')
literals_indexes = []
comments = []
for line in lines:
    if(line[0] == '#'):
        comments.append(line)
    else:
        index_apos = []
        index_quote = []
        index = []
        for (i,char) in enumerate(line):
            if(char == "'"):
                index_apos.append(i)
            if(char == '"'):
                index_quote.append(i)
            if(char == '#'):
                index.append(i)
        literals_indexes.append([index_apos,index_quote,index])

for comment in comments:
    lines.remove(comment)
comments = []
for indexes in literals_indexes:
    if(indexes[2] != []):
        for hashes in indexes[2]:
            count_apos = 0
            count_quotes = 0
            append_flag = False
            if(indexes[0] != []):
                for apos in indexes[0]:
                    if(apos < hashes):
                        count_apos += 1
                    else:
                        break
            if(indexes[1] != []):
                for quotes in indexes[1]:
                    if(quotes < hashes):
                        count_quotes += 1
                    else:
                        break
            if(((count_apos % 2) == 0) and ((count_quotes % 2) == 0)):
                append_flag = True
                comments.append(hashes)
                break
        if(not append_flag):
            comments.append(0)
    else:
        comments.append(0)

new_text = []
for (line,index) in zip(lines,comments):
    if(index != 0):
        line = line.replace(line[index:],"")
    new_text.append(line)
new_text = n'.join(new_text)

Хотя это не лучшее решение, это сработало для меня. Надеюсь, мне удалось написать содержательную статью о своем опыте. Я счастливый человек после того, как реализовал эту крошечную функцию.

Я хорошо знаком с такими популярными инструментами, как регулярные выражения, и не стал бы удивляться, если бы кто-то придумал какое-нибудь регулярное выражение для удаления комментариев (хотя это было бы непросто).


Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE