我正在使用python来浏览一个文件并删除任何注释。只要注释不在双引号内,注释就被定义为哈希及其右边的任何内容。我目前有一个解决方案,但它似乎不太理想:
filelines = []
r = re.compile('(".*?")')
for line in f:
m = r.split(line)
nline = ''
for token in m:
if token.find('#') != -1 and token[0] != '"':
nline += token[:token.find('#')]
break
else:
nline += token
filelines.append(nline)
有没有一种方法可以在没有for循环的引号中找到第一个哈希(即通过正则表达式)?
示例:
' "Phone #":"555-1234" ' -> ' "Phone #":"555-1234" '
' "Phone "#:"555-1234" ' -> ' "Phone "'
'#"Phone #":"555-1234" ' -> ''
' "Phone #":"555-1234" #Comment' -> ' "Phone #":"555-1234" '
编辑:这里是由user2357112创建的纯正则表达式解决方案。我测试了它,它运行得很好:
filelines = []
r = re.compile('(?:"[^"]*"|[^"#])*(#)')
for line in f:
m = r.match(line)
if m != None:
filelines.append(line[:m.start(1)])
else:
filelines.append(line)
有关此正则表达式工作原理的更多细节,请参见他的答复。
Edit2:下面是user2357112代码的一个版本,我对其进行了修改,以说明转义字符(\")。这段代码还通过包含对字符串结尾($)的检查来消除'if‘:
filelines = []
r = re.compile(r'(?:"(?:[^"\\]|\\.)*"|[^"#])*(#|$)')
for line in f:
m = r.match(line)
filelines.append(line[:m.start(1)])
发布于 2013-07-22 07:36:50
r'''(?: # Non-capturing group
"[^"]*" # A quote, followed by not-quotes, followed by a quote
| # or
[^"#] # not a quote or a hash
) # end group
* # Match quoted strings and not-quote-not-hash characters until...
(#) # the comment begins!
'''
这是一个冗长的正则表达式,设计用于在一行上操作,所以请确保使用re.VERBOSE
标志,并一次只输入一行。如果存在第一个未引用的散列,它将捕获第一个未引用的散列,因此可以使用match.start(1)
获取索引。它不处理反斜杠转义,如果你想要将反斜杠-转义引号放在一个字符串中。这是未经检验的。
发布于 2013-07-22 07:40:51
可以使用此脚本删除注释:
import re
print re.sub(r'(?s)("[^"\\]*(?:\\.[^"\\]*)*")|#[^\n]*', lambda m: m.group(1) or '', '"Phone #"#:"555-1234"')
这样做的目的是捕捉双引号中包含的第一部分,并在搜索锐利之前将其替换为自己:
(?s) # the dot matches newlines too
( # open the capture group 1
" # "
[^"\\]* # all characters except a quote or a backslash
# zero or more times
(?: # open a non-capturing group
\\. # a backslash and any character
[^"\\]* #
)* # repeat zero or more times
" # "
) # close the capture group 1
| # OR
#[^\n]* # a sharp and zero or one characters that are not a newline.
发布于 2013-07-22 08:10:08
这段代码太难看了,我不得不把它发出来。
def remove_comments(text):
char_list = list(text)
in_str = False
deleting = False
for i, c in enumerate(char_list):
if deleting:
if c == '\n':
deleting = False
else:
char_list[i] = None
elif c == '"':
in_str = not in_str
elif c == '#':
if not in_str:
deleting = True
char_list[i] = None
char_list = filter(lambda x: x is not None, char_list)
return ''.join(char_list)
不过,似乎很管用。虽然我不确定它如何处理windows和linux之间的换行符。
https://stackoverflow.com/questions/17791143
复制