0

a=b c=d e=f次のような辞書になるはずの多くの値を解析するための正規表現があります{'a': 'b', 'c':'d', 'e':'f'}\私が使用した本当に単純な正規表現の代わりに、ユーザーが使用して値をエスケープできるようにしたかったので、((?:[^\\\s=]+|\\.)+)追加(?:^|\s)(?=\s|$)たため、式は部分的な結果と一致しません。

>>> import re
>>> reg = re.compile(r'(?:^|\s)([\w\d]+)=((?:[^\\\s=]+|\\.)+)(?=\s|$)')
>>> s = r'a=b c=d e=one\two\three'
>>> reg.findall(s)
[('a', 'b'), ('c', 'd'), ('e', 'one\\two\\three')]

しかし、その後、誰かがやってきて=、物事の右側に挿入されました.

>>> s = r'a=b c=d e=aaaaaaaaaaaaaaaaaaaaaaaaaa\bbbbbbbbbbbbbbbbbbbbbbbbbbbb\cccc
    ccccc=dddddddddddddddd\eeeeeeeeeeeeeee'    
>>> reg.findall(s)

そして、スクリプトはこの行で動かなくなりました (私は数時間待っていましたが、終了しませんでした)。

質問: これは貧弱な正規表現ですか (なぜですか? どうやって書きましたか?)、それとも正規表現の実装のバグですか?

注: この問題の解決策を求めているわけではありません。数時間で終了しない理由が気になります。 findall()

4

3 に答える 3

1

あなたの問題は、繰り返しをネストし、リエンジンがそれらの間で可能なすべての分布を試みるように見えることです:

r'(?:^|\s)([\w\d]+)=((?:[^\\\s=]+|\\.)+)(?=\s|$)'
                                ^     ^

より良い:

r'(?:^|\s)([\w\d]+)=((?:[^\\\s=]|\\.)+)(?=\s|$)'

実際、findall は終了します (またはメモリ不足になります)。これを試すことができます

s = r'a=b c=d e=aaaaaaa\bbbbbbbb\ccccccccc=ddddddddd\eeeee'

e=「 」の後に連続して文字を追加します

于 2013-06-12T08:52:49.787 に答える
0
于 2013-06-12T08:44:07.847 に答える
0
>>> import re
>>> reg = re.compile(r'(\w+)=(\S+)')
>>> dict(reg.findall(r'a=b c=d e=one\two\three'))
{'e': 'one\\two\\three', 'a': 'b', 'c': 'd'}
>>> dict(reg.findall(r'a=b c=d e=aaaaaaaaaaaaaaaaaaaaaaaaaa\bbbbbbbbbbbbbbbbbbbbbbbbbbbb\ccccccccc=dddddddddddddddd\eeeeeeeeeeeeeee'))
{'e': 'aaaaaaaaaaaaaaaaaaaaaaaaaa\\bbbbbbbbbbbbbbbbbbbbbbbbbbbb\\ccccccccc=dddddddddddddddd\\eeeeeeeeeeeeeee', 'a': 'b', 'c': 'd'}
于 2013-06-12T08:52:30.663 に答える