web-dev-qa-db-fra.com

Pourquoi re.sub remplace-t-il le modèle entier, pas seulement un groupe de capture en son sein?

re.sub('a(b)','d','abc') donne dc, pas adc.

Pourquoi re.sub remplacer tout le groupe de capture, au lieu de simplement capturer le groupe '(b)'?

11
Nick

Parce qu'il est censé remplacer toute l'occurrence du motif:

Renvoie la chaîne obtenue en remplaçant les occurrences non chevauchantes les plus à gauche du motif dans la chaîne par le remplacement de remplacement.

S'il ne devait remplacer que certains sous-groupes, les expressions rationnelles complexes avec plusieurs groupes ne fonctionneraient pas. Il existe plusieurs solutions possibles:

  1. Spécifiez le modèle dans son intégralité: re.sub('ab', 'ad', 'abc') - mon préféré, car il est très lisible et explicite.
  2. Capturez les groupes que vous voulez pour conserver, puis faites-y référence dans le modèle (notez qu'il doit s'agir d'une chaîne brute pour éviter de s'échapper): re.sub('(a)b', r'\1d', 'abc')
  3. Similaire à l'option précédente: fournissez une fonction de rappel en tant qu'argument repl et faites-la traiter l'objet Match et renvoyer le résultat requis.
  4. Utilisez lookbehinds/lookaheds, qui ne sont pas inclus dans la correspondance, mais affectent la correspondance: re.sub('(?<=a)b', r'd', 'abxb') renvoie adxb. Le ?<= au début du groupe dit "c'est un coup d'oeil".
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)
    )

Comme ci-dessus, nous compilons d'abord un modèle d'expression régulière avec un drapeau insensible à la casse.

Ensuite, nous vérifions si le texte correspond au modèle, si c'est le cas, nous référençons le seul groupe dans le modèle d'expression régulière (âge) avec le numéro de groupe\1.

0
Gnoliz