9
votes

Remplacement de chaîne sensible à la casse en python

Je dois remplacer une chaîne dans la voie sensible. Par exemple

abc -> def
Abc -> Def
aBc -> dEf
abC -> deF


4 commentaires

@Mark: Wiki utilise des caractères supérieurs / inférieurs pour le nom de wiki. J'ai besoin de remplacer certains noms de wiki.


Quel serait le remplacement de 'WSG'?


Il est possible que la réponse à la question que vous avez posée ne vous aide pas avec le problème que vous essayez de résoudre. Et si l'avant et après avoir différentes longueurs?


@Mark: En réalité, je ne suis que remplacer les chaînes basées sur un petit ensemble de règles, sans essayer de remplacer toutes les combinaisons de noms de wiki possibles. Donc, la réponse de Wilhelmtell fonctionne efficacement pour mes fins. Merci pour les réponses.


7 Réponses :


0
votes

Pas la manière la plus efficace, et c'est très brut, mais probablement quelque chose comme ça pourrait fonctionner:

def case_insensitive_replace(string, old, new):
    upper_indices = [idx for idx, char in enumerate(string) if char.isupper()]
    replaced = list(string.lower().replace(old.lower(), new.lower()))
    for idx in upper_indices:
        replaced[idx] = replaced[idx].upper()
    return "".join(replaced)


0 commentaires

8
votes
from string import maketrans

"Abc".translate(maketrans("abcABC", "defDEF"))

2 commentaires

Cela suppose que le même personnage n'apparaît pas deux fois dans la chaîne d'entrée.


Cela ne fonctionnera pas pour remplacer "FOO" avec "bar" car le caractère "O" doit être mappé sur "A" ou "R" en fonction du contexte.



6
votes

Voici une méthode utilisant des expressions régulières. Le point clé est que lorsqu'il trouve une correspondance, il modifie d'abord la chaîne de remplacement pour correspondre au boîtier de la chaîne correspondante. Cela fonctionne car re7 code> peut prendre une fonction de remplacement au lieu d'une seule chaîne.

def -> def
Def -> Def
dEf -> dEf
deF -> deF


0 commentaires

0
votes

Je comprends que vous souhaitez modifier le deuxième boîtier de cordes selon la première chaîne. Ai-je raison? Donc, ma solution est la suivante. String S2 Modifier son étui en fonction de la chaîne correspondante S1. Le résultat stocke dans S3. Une hypothèse ici est que les deux chaînes ont la même longueur.

s1 = "AaBb"
s2 = "cdef"
s3 = ""
index = 0
length = len(s1)

while(True):
    if s1[index].isupper():
        temp = s2[index].upper()
    else:
        temp = s2[index].lower()
    s3 = s3 + temp
    index +=1
    if index == length:
        break
print s3


0 commentaires

1
votes

Long time Lurker, pensais que je posterais une suggestion ici car certaines d'entre elles semblent assez compliquées. XXX

Il suppose que les deux chaînes ont la même longueur, mais vous pouvez facilement remplacer facilement le Lambda avec une fonction appropriée et vérifie pour aucun sur la première entrée.


0 commentaires

0
votes

Cela fonctionnera, bien que vous souhaitiez probablement ajouter des vérifications sur lesquelles les longueurs de la chaîne sont les mêmes:

string1 = "AbcDEFghiJKLmnO"
string2 = "some other text"

string2 = "".join((string2[i].upper() if string1[i].isupper() else string2[i].lower() 
                   for i in range(len(string1))))


0 commentaires

5
votes

Élargir sur la réponse de Mark Byers's, voici une solution qui fonctionne pour le texte de remplacement de toute longueur. de
L'astuce consiste à envoyer une fonction à Re2 () .

de De dE de DE
def Def dEf deF DEF
defg Defg dEfg deFg DEFG


0 commentaires