Remplacement des instances d'un caractère dans une chaîne


120

Ce code simple qui essaie simplement de remplacer les points-virgules (aux positions spécifiées par i) par des deux-points ne fonctionne pas:

for i in range(0,len(line)):
     if (line[i]==";" and i in rightindexarray):
         line[i]=":"

Cela donne l'erreur

line[i]=":"
TypeError: 'str' object does not support item assignment

Comment puis-je contourner ce problème pour remplacer les points-virgules par des deux-points? L'utilisation de replace ne fonctionne pas car cette fonction ne prend aucun index - il peut y avoir des points-virgules que je ne veux pas remplacer.

Exemple

Dans la chaîne, je pourrais avoir n'importe quel nombre de points-virgules, par exemple "Hei der!; Hello there;!;"

Je sais lesquels je veux remplacer (j'ai leur index dans la chaîne). L'utilisation de replace ne fonctionne pas car je ne peux pas utiliser d'index avec elle.


1
Connaissez-vous le str.replace()BIF?
— LarsVegas

2
Oui, comme je l'ai expliqué dans la question. J'ai également expliqué pourquoi cela ne fonctionne pas pour moi.
— The Unfun Cat

Utilisez str.find() plutôt pour trouver la position du point-virgule, puis utilisez le découpage pour extraire la sous-chaîne.
— LarsVegas

1
Vous devez alors être plus précis dans ce qui constitue un remplacement valide; votre code non fonctionnel remplacerait tous les points-virgules de la chaîne s'il était mutable.
— Martijn Pieters

1
@TheUnfunCat: Comment obtenez-vous les indices en premier lieu? Il y a peut-être une meilleure solution à tout (par exemple, les regex)
— nneonneo

Réponses:


207

Les chaînes en python sont immuables, vous ne pouvez donc pas les traiter comme une liste et les affecter à des index.

Utilisez à la .replace()place:

line = line.replace(';', ':')

Si vous ne devez remplacer que certains points-virgules, vous devrez être plus précis. Vous pouvez utiliser le découpage pour isoler la section de la chaîne à remplacer dans:

line = line[:10].replace(';', ':') + line[10:]

Cela remplacera tous les points-virgules dans les 10 premiers caractères de la chaîne.


Cela fonctionne-t-il avec les caractères Unicode? Cela ne semble pas fonctionner pour moi.
— Steven2163712

@ Steven2163712: Tout le texte est Unicode, donc oui, cela fonctionne bien avec tous les caractères. Sans un exemple concret, je ne peux pas vous aider à résoudre votre problème spécifique.
— Martijn Pieters

62

Vous pouvez faire ce qui suit, pour remplacer n'importe quel caractère par un caractère respectif à un index donné, si vous ne souhaitez pas utiliser .replace()

word = 'python'
index = 4
char = 'i'

word = word[:index] + char + word[index + 1:]
print word

o/p: pythin

7
Cela devrait être la réponse acceptée, répond directement à la question. C'est la méthode la plus simple que j'ai trouvée jusqu'à présent.
— Flare Cat

24

Transformez la chaîne en une liste; alors vous pouvez changer les caractères individuellement. Ensuite, vous pouvez le remettre avec .join:

s = 'a;b;c;d'
slist = list(s)
for i, c in enumerate(slist):
    if slist[i] == ';' and 0 <= i <= 3: # only replaces semicolons in the first part of the text
        slist[i] = ':'
s = ''.join(slist)
print s # prints a:b:c;d

6

Si vous souhaitez remplacer un seul point-virgule:

for i in range(0,len(line)):
 if (line[i]==";"):
     line = line[:i] + ":" + line[i+1:]

Mais Havent l'a testé.


3
Cela fonctionnera (+1), mais est assez inefficace, car vous créez une nouvelle chaîne à chaque fois que vous rencontrez un ';'
— inspectorG4dget

@ inspectorG4dget, vous avez raison, c'est une solution rapide et sale - une seule fois -.
— Vic

En fait, @ inspectorG4dget, la réponse acceptée ne souffre-t-elle pas du même problème?
— Vic

2
line.replace(src,dst)ne fait pas. line[:10].replace(src,dst) + line[10:]fait, mais avec beaucoup moins de gravité. Supposons line = ';'*12. Votre solution créera une nouvelle chaîne 12 fois. La solution acceptée le fera une fois.
— inspectorG4dget

3

Cela devrait couvrir un cas un peu plus général, mais vous devriez pouvoir le personnaliser selon vos besoins

def selectiveReplace(myStr):
    answer = []
    for index,char in enumerate(myStr):
        if char == ';':
            if index%2 == 1: # replace ';' in even indices with ":"
                answer.append(":")
            else:
                answer.append("!") # replace ';' in odd indices with "!"
        else:
            answer.append(char)
    return ''.join(answer)

J'espère que cela t'aides


3

Vous ne pouvez pas simplement attribuer une valeur à un caractère de la chaîne. Utilisez cette méthode pour remplacer la valeur d'un caractère particulier:

name = "India"
result=name .replace("d",'*')

Sortie: In * ia

Aussi, si vous voulez remplacer say * pour toutes les occurrences du premier caractère à l'exception du premier caractère, par exemple. string = sortie babble = ba ** le

Code:

name = "babble"
front= name [0:1]
fromSecondCharacter = name [1:]
back=fromSecondCharacter.replace(front,'*')
return front+back

1

Si vous remplacez par une valeur d'index spécifiée dans la variable 'n', essayez ce qui suit:

def missing_char(str, n):
 str=str.replace(str[n],":")
 return str

1
Le problème avec cette solution est qu'elle remplacerait toutes les occurrences du caractère à la position n et que asker veut seulement remplacer cette occurrence spécifique
— shivram.ss

Exactement, mauvaise solution!
— Erhard Dinhobl

1

Que dis-tu de ça:

sentence = 'After 1500 years of that thinking surpressed'

sentence = sentence.lower()

def removeLetter(text,char):

    result = ''
    for c in text:
        if c != char:
            result += c
    return text.replace(char,'*')
text = removeLetter(sentence,'a')

1

pour utiliser efficacement la méthode .replace () sur une chaîne sans créer de liste séparée, par exemple, jetez un œil à la liste nom d'utilisateur contenant une chaîne avec un espace blanc, nous voulons remplacer l'espace blanc par un trait de soulignement dans chacune des chaînes de nom d'utilisateur.

usernames = ["Joey Tribbiani", "Monica Geller", "Chandler Bing", "Phoebe Buffay"]

pour remplacer les espaces blancs dans chaque nom d'utilisateur, envisagez d'utiliser la fonction range en python.

for i in range(len(usernames)):
    usernames[i] = usernames[i].lower().replace(" ", "_")

print(usernames)

0

Pour remplacer un caractère à un index spécifique, la fonction est la suivante:

def replace_char(s , n , c):
    n-=1
    s = s[0:n] + s[n:n+1].replace(s[n] , c) + s[n+1:]
    return s

où s est une chaîne, n est un index et c est un caractère.


0

J'ai écrit cette méthode pour remplacer des caractères ou remplacer des chaînes à une instance spécifique. les instances commencent à 0 (cela peut facilement être changé en 1 si vous changez l'argument facultatif inst sur 1 et la variable test_instance sur 1.

def replace_instance(some_word, str_to_replace, new_str='', inst=0):
    return_word = ''
    char_index, test_instance = 0, 0
    while char_index < len(some_word):
        test_str = some_word[char_index: char_index + len(str_to_replace)]
        if test_str == str_to_replace:
            if test_instance == inst:
                return_word = some_word[:char_index] + new_str + some_word[char_index + len(str_to_replace):]
                break
            else:
                test_instance += 1
        char_index += 1
    return return_word

0

Tu peux le faire:

string = "this; is a; sample; ; python code;!;" #your desire string
result = ""
for i in range(len(string)):
    s = string[i]
    if (s == ";" and i in [4, 18, 20]): #insert your desire list
        s = ":"
    result = result + s
print(result)

0

names = ["Joey Tribbiani", "Monica Geller", "Chandler Bing", "Phoebe Buffay"]

noms d'utilisateur = []

for i in names:
    if " " in i:
        i = i.replace(" ", "_")
    print(i)

o, p Joey_Tribbiani Monica_Geller Chandler_Bing Phoebe_Buffay


1
Merci, Muhammad je suis un débutant je ferai de mon mieux.
— Kasem007
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.