删除不在引号内的哈希注释

Gil*_*pie 5 python regex quotes comments strip

我正在使用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)
Run Code Online (Sandbox Code Playgroud)

有没有办法在没有for循环的情况下找到不在引号内的第一个散列(即通过正则表达式?)

例子:

' "Phone #":"555-1234" ' -> ' "Phone #":"555-1234" '
' "Phone "#:"555-1234" ' -> ' "Phone "'
'#"Phone #":"555-1234" ' -> ''
' "Phone #":"555-1234" #Comment' -> ' "Phone #":"555-1234" '
Run Code Online (Sandbox Code Playgroud)

编辑:这是一个由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)
Run Code Online (Sandbox Code Playgroud)

有关此正则表达式如何工作的更多详细信息,请参阅他的回复.

Edit2:这是我修改为用于转义字符(\")的代码的user2357112代码版本.此代码还通过包含对字符串结尾($)的检查来消除'if':

filelines = []
r = re.compile(r'(?:"(?:[^"\\]|\\.)*"|[^"#])*(#|$)')
for line in f:
    m = r.match(line)
    filelines.append(line[:m.start(1)])
Run Code Online (Sandbox Code Playgroud)

use*_*ica 3

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!
'''
Run Code Online (Sandbox Code Playgroud)

这是一个详细的正则表达式,设计为在单行上运行,因此请确保使用该re.VERBOSE标志并一次输入一行。如果有的话,它将捕获第一个未加引号的哈希值作为组 1,因此您可以使用它match.start(1)来获取索引。如果您希望能够在字符串中放置反斜杠转义的引号,它不处理反斜杠转义。这是未经测试的。