5

Python 2.7を使用re.subして、次の例では単純な後方参照を使用しています。

re.sub('-{1,2}', r'\g<0> ', 'pro----gram-files')

期待どおりに次の文字列を出力します。

'pro-- -- gram- files'

次の例は同じだと思いますが、そうではありません。

def dashrepl(matchobj):
    return r'\g<0> '
re.sub('-{1,2}', dashrepl, 'pro----gram-files')

これにより、次の予期しない出力が得られます。

'pro\\g<0> \\g<0> gram\\g<0> files'

2 つの例の出力が異なるのはなぜですか? これを説明するドキュメントで何か見逃していましたか? この動作が私が期待したものよりも好ましいという特定の理由はありますか? 置換関数で後方参照を使用する方法はありますか?

4

2 に答える 2

5

目標を達成するためのより簡単な方法があるので、それらを使用できます。

既に見たように、置換関数は引数として一致オブジェクトを取得します。

このオブジェクトには、group()代わりに使用できるメソッドがあります。

def dashrepl(matchobj):
    return matchobj.group(0) + ' '

正確に結果が得られます。


しかし、あなたは完全に正しいです-ドキュメントはそのように少し混乱しています:

彼らはrepl議論を説明します:

repl文字列または関数にすることができます。文字列の場合、その中のバックスラッシュ エスケープが処理されます。

が関数の場合repl、重複しないパターンの出現ごとに呼び出されます。この関数は単一の一致オブジェクト引数を取り、置換文字列を返します。

これは、関数によって返される「置換文字列」がバックスラッシュ エスケープの処理にも適用されるかのように解釈できます。

しかし、この処理は「ひもである」という場合に限って記述されているので、一目瞭然ではありますが、より明確になります。

于 2012-10-18T16:14:36.247 に答える
4

関数を に渡すとre.sub、一致を関数から返された文字列に置き換えることができます。基本的にre.sub、関数または文字列を渡すかどうかに応じて、異なるコード パスを使用します。そして、はい、これは実際に望ましいことです。withの一致とfoowithの一致を置き換えたい場合を考えてみましょう。次に、次のように記述できます。barbazqux

repdict = {'foo':'bar','baz':'qux'}
re.sub('foo|baz',lambda match: repdict[match.group(0)],'foo')

2回のパスでこれを行うことができると主張することができますが、repdict次のように見える場合はそれを行うことはできません{'foo':'baz','baz':'qux'}

そして、後方参照でそれを行うことはできないと思います(少なくとも簡単ではありません)。

于 2012-10-18T16:08:29.477 に答える