web-dev-qa-db-fra.com

Utilisation d'une expression régulière pour remplacer les lettres majuscules répétées en python par une seule lettre minuscule

J'essaie de remplacer toutes les occurrences de lettres majuscules qui se répètent deux fois dans une chaîne avec une seule occurrence de cette lettre en minuscule. J'utilise l'expression régulière suivante et elle peut correspondre aux lettres majuscules répétées, mais je ne sais pas comment rendre la lettre remplacée par une minuscule.

import re
s = 'start TT end'
re.sub(r'([A-Z]){2}', r"\1", s)
>>> 'start T end'

Comment puis-je faire le "\ 1" minuscule? Ne devrais-je pas utiliser une expression régulière pour faire cela?

26
ajt

Passer une fonction en tant qu'argument repl. Le MatchObject est passé à cette fonction et .group(1) donne le premier sous-groupe entre parenthèses:

import re
s = 'start TT end'
callback = lambda pat: pat.group(1).lower()
re.sub(r'([A-Z]){2}', callback, s)

EDIT
Et oui, vous devriez utiliser ([A-Z])\1 au lieu de ([A-Z]){2} afin de pas correspondre par exemple. AZ. (Voir @ bobince's answer .)

import re
s = 'start TT end'
re.sub(r'([A-Z])\1', lambda pat: pat.group(1).lower(), s) # Inline

Donne:

'start t end'
41
jensgram

Vous ne pouvez pas changer la casse dans une chaîne de remplacement. Vous auriez besoin d'une fonction de remplacement:

>>> def replacement(match):
...     return match.group(1).lower()
... 
>>> re.sub(r'([A-Z])\1', replacement, 'start TT end')
'start t end'
6
bobince

Vous pouvez le faire avec une expression régulière, il suffit de passer une fonction en remplacement, telle que la documentation say. Le problème est votre modèle.

Dans ce cas, votre modèle correspond à des exécutions de any deux lettres majuscules. Je vous laisse le modèle actuel, mais il commence par AA|BB|CC|.

1

Le paramètre 'repl' qui identifie le remplaçant peut être une chaîne (comme vous l'avez ici) ou une fonction. Cela fera ce que vous souhaitez:

import re

def toLowercase(matchobj):
   return matchobj.group(1).lower()

s = 'start TT end'
re.sub(r'([A-Z]){2}', toLowercase, s)
>>> 'start t end'
0
bgporter

Essaye ça:

def tol(m):
   return m.group(0)[0].lower()

s = 'start TTT AAA end'
re.sub(r'([A-Z]){2,}', tol, s)

Notez que cela ne remplace pas les lettres majuscules. Si vous voulez le faire, utilisez r'([A-Z]){1,}'.

0
khachik

ATTENTION! Ce message n'a pas de re comme demandé. Continuez avec votre propre responsabilité!

Je ne sais pas dans quelle mesure des cas critiques sont possibles, mais c’est comme cela que Python normal fait mon codage naïf.

import string
s = 'start TT end AAA BBBBBBB'
for c in string.uppercase:
    s = s.replace(c+c,c.lower())
print s
""" Output:
start t end aA bbbB
"""
0
Tony Veijalainen