1

次の正規表現が 'a' と 'b' の間で空の文字列を返すのはなぜですか?

In [48]: pat = re.compile(".*?(?=,|$)")

In [49]: it = pat.findall('a,b')

In [50]: it
Out[50]: ['a', '', 'b', '']

コンマ間の部分文字列を抽出するにはどうすればよいですか?

編集:正規表現を使用してそれを行う方法に興味があります。

編集: 正規表現は、この入力 ",," でツリーの空の文字列を正常に抽出する必要があります。

4

3 に答える 3

2
  • .*?a次の文字が であるため、最初に一致し,ます。
  • 正規表現エンジンは . の前の位置になりました,
  • これで、.*?の前の空の文字列に一致します,(アスタリスクによってゼロ長の一致が許可されるため)。
  • 正規表現エンジンは、長さが 0 の一致の後に 1 文字進めます (そうしないと、ここで永久にスタックしてしまいます)。
  • .*?b文字列の末尾にいるため、一致するようになりました。
  • 正規表現エンジンが文字列の末尾になりました。
  • .*?文字列の末尾の前の空の文字列に一致します。
  • 弦が尽きた。正規表現エンジンが終了します。

最善の解決策は、コンマで単純に分割することです。

正規表現の使用を主張する場合、( docsによると)別の一致の先頭re.findall()に触れない限り、空の一致が含まれるため、もう少し複雑になります。つまり、使用した先読みの代わりに、肯定的な後読みアサーションを使用する必要があります。

これは、Python が後読みで可変幅の正規表現を許可していないため (ため息)、同じアサーションで区切り文字と文字列の開始アンカーをチェックできないことを意味します。しかし、それは次のように可能です:

>>> re.findall("(?:^|(?<=,))[^,]*", "a,b,,c")
['a', 'b', '', 'c']
于 2013-11-05T18:19:49.253 に答える
0

問題は、正規表現全体が、先読みアサーションの前の「オプションの」文字消費で構成されていることだと思います。

一致位置が進むにつれて、何かと一致するか、または一致しないかのいずれかになります。
何も一致しない場合、配列は . で埋められます''

したがってa,b、'a'、''、'b'、''
に一致します。最後の '' は文字列の末尾です (.*$空の文字列に一致するのと同様)。

于 2013-11-05T19:21:33.480 に答える