Удаление однострочных комментариев: 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)
Хотя это не лучшее решение, это сработало для меня. Надеюсь, мне удалось написать содержательную статью о своем опыте. Я счастливый человек после того, как реализовал эту крошечную функцию.
Я хорошо знаком с такими популярными инструментами, как регулярные выражения, и не стал бы удивляться, если бы кто-то придумал какое-нибудь регулярное выражение для удаления комментариев (хотя это было бы непросто).
Оригинал