web-dev-qa-db-ja.com

re.subがパターン内のキャプチャグループだけでなく、パターン全体を置き換えるのはなぜですか?

re.sub('a(b)','d','abc')dcではなくadcを生成します。

どして re.subキャプチャグループだけでなく、キャプチャグループ全体を置き換えます '(b)'?

11
Nick

それはパターンの出現全体を置き換えることになっているので:

String内のパターンの左端の重複しないオカレンスを置換replで置き換えることによって取得された文字列を返します。

一部のサブグループのみを置き換える場合、複数のグループを持つ複雑な正規表現は機能しません。考えられる解決策はいくつかあります。

  1. パターンを完全に指定します:re.sub('ab', 'ad', 'abc')-非常に読みやすく明示的であるため、私のお気に入りです。
  2. 保存するグループwantをキャプチャして、パターンでそれらを参照します(エスケープを回避するために生の文字列である必要があります):re.sub('(a)b', r'\1d', 'abc')
  3. 前のオプションと同様:repl引数としてコールバック関数を提供し、Matchオブジェクトを処理して必要な結果を返すようにします。
  4. 照合には含まれていませんが照合に影響を与えるlookbehinds/lookahedsを使用してください:re.sub('(?<=a)b', r'd', 'abxb')adxbを生成します。 ?<=グループの最初に「先読みです」と書かれています。
6
yeputons
import re

pattern = re.compile(r"I am (\d{1,2}) .*", re.IGNORECASE)

text = "i am 32 years old"

if re.match(pattern, text):
    print(
        re.sub(pattern, r"Your are \1 years old.", text, count=1)
    )

上記のように、最初に大文字と小文字を区別しないフラグを使用して正規表現パターンをコンパイルします。

次に、テキストがパターンと一致するかどうかをチェックし、一致する場合は、グループ番号\ 1の正規表現パターン(年齢)の唯一のグループを参照します。

0
Gnoliz