Substituindo instâncias de um caractere em uma string

120

Este código simples que simplesmente tenta substituir o ponto-e-vírgula (em posições especificadas por i) por dois-pontos não funciona:

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

Dá o erro

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

Como posso contornar isso para substituir o ponto-e-vírgula por dois-pontos? Usar substituir não funciona porque essa função não leva nenhum índice - pode haver alguns pontos-e-vírgulas que eu não quero substituir.

Exemplo

Na string, posso ter qualquer número de ponto e vírgula, por exemplo, "Hei der!; Hello there;!;"

Eu sei quais desejo substituir (tenho seu índice na string). O uso de substituir não funciona porque não consigo usar um índice com ele.

The Unfun Cat
fonte
1
Voce sabe o str.replace() BIF?
LarsVegas
2
Sim, como expliquei na pergunta. Também expliquei por que isso não funciona para mim.
The Unfun Cat
Em str.find() vez disso, use para encontrar a posição do ponto-e-vírgula e, em seguida, use o fatiamento para extrair a substring.
LarsVegas
1
Você precisa ser mais específico no que constitui uma substituição válida; seu código não funcional substituiria todos os pontos-e-vírgulas na string se fosse mutável.
Martijn Pieters
1
@TheUnfunCat: Em primeiro lugar, como você está obtendo os índices? Pode haver uma solução melhor para tudo (por exemplo,
regexes

Respostas:

207

Strings em python são imutáveis, então você não pode tratá-los como uma lista e atribuir a índices.

Usar .replace() lugar:

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

Se você precisar substituir apenas alguns pontos-e-vírgulas, será necessário ser mais específico. Você pode usar o fatiamento para isolar a seção da string para substituir em:

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

Isso substituirá todos os pontos-e-vírgulas nos primeiros 10 caracteres da string.

Martijn Pieters
fonte
Isso funciona com caracteres Unicode? Não parece funcionar para mim.
Steven2163712
@ Steven2163712: Todo o texto é Unicode, então sim, funciona bem com todos os caracteres. Sem um exemplo concreto, não posso ajudá-lo a resolver seu problema específico.
Martijn Pieters
62

Você pode fazer o seguinte, para substituir qualquer caractere por um respectivo caractere em um determinado índice, se não desejar usar .replace()

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

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

o/p: pythin
Dineshs91
fonte
7
Esta deve ser a resposta aceita, responde diretamente à pergunta. Este é o método mais fácil que encontrei até agora.
Flare Cat
24

Transforme a string em uma lista; então você pode mudar os personagens individualmente. Então você pode colocá-lo de volta junto com .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
fonte
6

Se você deseja substituir um único ponto e vírgula:

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

Embora ainda não tenha testado.

Vic
fonte
3
Isso funcionará (+1), mas é bastante ineficiente, pois você está criando uma nova string toda vez que encontrar um ';'
inspectorG4dget
@ inspectorG4dget, você está certo, é uma solução rápida e suja - única.
Vic
Na verdade, @ inspectorG4dget, a resposta aceita não sofre do mesmo problema?
Vic
2
line.replace(src,dst)não. line[:10].replace(src,dst) + line[10:]faz, mas com muito menos gravidade. Suponha line = ';'*12. Sua solução construirá uma nova string 12 vezes. A solução aceita o fará uma vez.
inspectorG4dget
3

Isso deve abranger um caso um pouco mais geral, mas você deve ser capaz de personalizá-lo para seu propósito

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)

Espero que isto ajude

inspectorG4dget
fonte
3

Você não pode simplesmente atribuir valor a um caractere na string. Use este método para substituir o valor de um caractere específico:

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

Saída: In * ia

Além disso, se você deseja substituir, diga * para todas as ocorrências do primeiro caractere, exceto o primeiro caractere, por exemplo. string = balbucio output = ba ** le

Código:

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

Se você estiver substituindo por um valor de índice especificado na variável 'n', tente o seguinte:

def missing_char(str, n):
 str=str.replace(str[n],":")
 return str
Bipin Shetty
fonte
1
O problema com esta solução é que ela substituiria todas as ocorrências do caractere na posição ne o asker deseja apenas substituir aquela ocorrência específica
shivram.ss
Exatamente, solução ruim!
Erhard Dinhobl
1

Que tal agora:

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
fonte
1

para usar o método .replace () efetivamente na string sem criar uma lista separada, por exemplo, dê uma olhada na lista de nome de usuário que contém a string com algum espaço em branco, queremos substituir o espaço em branco por um sublinhado em cada string do nome de usuário.

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

para substituir os espaços em branco em cada nome de usuário, considere o uso da função range em python.

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

print(usernames)
N.Samuel
fonte
0

Para substituir um caractere em um índice específico, a função é a seguinte:

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

onde s é uma string, n é um índice ec é um caractere.

Sanket Hire
fonte
0

Escrevi este método para substituir caracteres ou substituir strings em uma instância específica. as instâncias começam em 0 (isso pode ser facilmente alterado para 1 se você alterar o argumento opcional inst para 1 e a variável test_instance para 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
fonte
0

Você consegue fazer isso:

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
fonte
0

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

nomes de usuário = []

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

o, p Joey_Tribbiani Monica_Geller Chandler_Bing Phoebe_Buffay

Kasem007
fonte
1
Obrigado, Muhammad, sou um iniciante e farei o meu melhor.
Kasem007