17

次の点を考慮してください。

>>> import re
>>> a = "first:second"
>>> re.findall("[^:]*", a)
['first', '', 'second', '']
>>> re.sub("[^:]*", r"(\g<0>)", a)
'(first):(second)'

re.sub()の動作は最初はより理にかなっていますが、re.findall()の動作も理解できます。結局のところ、 コロン以外の文字のみで構成されるfirstとの間の空の文字列 (正確にはゼロ) に一致させることができますが、同じように動作しないのはなぜでしょうか?:re.sub()

最後のコマンドの結果は(first)():(second)()?

4

3 に答える 3

3

何らかの理由で、空の一致を処理するためのアルゴリズムが異なります。

の場合、次のfindallように動作します (の最適化されたバージョン): また、このルールを使用して結果の重複を回避します。i で長さ m の一致がある場合、i+m の前に次の一致を検索しないでください。あなたの例が返す理由は、コロンの直後ではなく、 andの['first', '', 'second', '']直後に空の一致が見つかるためです。その位置から始まる一致を探すと、完全な文字列が返されるためです。firstsecondsecond

の場合sub、違いは、お気づきのように、別の一致の直後に発生する長さ 0 の一致を明示的に無視することです。これが の予期しない動作を回避するのに役立つ理由はわかりますが、subなぜこの違いがあるのか​​ (たとえば、なぜfindall同じルールを使用しないのか) はわかりません。

于 2013-05-04T08:49:45.667 に答える
1
import re
a = "first:second:three"
print re.findall("[^:]*", a)

パターンに一致するすべての部分文字列を返します。ここでは、

>>> 
['first', '', 'second', '', 'three', '']

sub()は置換用であり、パターンの重複しない左端のオカレンスを代替で置換します。元

import re
a = "first:second:three"
print re.sub("[^:]*", r"smile", a)

与える

>>> 
smile:smile:smile

出現回数を 4 番目の引数 count で置き換えるように命令できます。

于 2013-05-04T07:30:05.970 に答える