5

私は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)])
4

3 に答える 3

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

これは冗長な正規表現であり、1 行で動作するように設計されているため、re.VERBOSEフラグを使用して一度に 1 行ずつフィードするようにしてください。引用符で囲まれていない最初のハッシュがあればグループ 1 としてキャプチャさmatch.start(1)れるため、インデックスを取得するために使用できます。バックスラッシュでエスケープされた引用符を文字列に入れたい場合は、バックスラッシュのエスケープを処理しません。これはテストされていません。

于 2013-07-22T15:36:50.657 に答える
0

このコードはとても醜いので、投稿する必要がありました。

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の間で改行文字をどのように処理するかはわかりませんが。

于 2013-07-22T16:10:08.697 に答える