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.

Le chat impertinent
la source
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.

Martijn Pieters
la source
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
Dineshs91
la source
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
nneonneo
la source
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é.

Vic
la source
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

inspecteurG4dget
la source
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
Darshan Jain
la source
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
Bipin Shetty
la source
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')
Dylan Maulucci
la source
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)
N.Samuel
la source
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.

Location Sanket
la source
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
Matt Farguson
la source
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)
shabgard tanha
la source
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

Kasem007
la source
1
Merci, Muhammad je suis un débutant je ferai de mon mieux.
Kasem007