Zastępowanie wystąpień znaku w ciągu

120

Ten prosty kod, który po prostu próbuje zastąpić średniki (w pozycjach określonych i) dwukropkami, nie działa:

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

Daje błąd

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

Jak mogę to obejść, aby zastąpić średniki dwukropkami? Korzystanie z zamiany nie działa, ponieważ ta funkcja nie przyjmuje indeksu - mogą istnieć średniki, których nie chcę zastępować.

Przykład

W ciągu znaków mógłbym mieć dowolną liczbę średników, np. „Hej!; Witam;!;”

Wiem, które z nich chcę zamienić (mam ich indeks w ciągu). Używanie zamiany nie działa, ponieważ nie mogę użyć z nim indeksu.

The Unfun Cat
źródło
1
Czy znasz str.replace()BIF?
LarsVegas
2
Tak, jak wyjaśniłem w pytaniu. Wyjaśniłem też, dlaczego to nie działa.
The Unfun Cat
Użyj str.find() zamiast tego, aby znaleźć pozycję średnika, a następnie użyj wycinania, aby wyodrębnić podciąg.
LarsVegas
1
Musisz wtedy bardziej szczegółowo określić, co stanowi ważny zamiennik; Twój niedziałający kod zastąpiłby wszystkie średniki w ciągu, gdyby był zmienny.
Martijn Pieters
1
@TheUnfunCat: W jaki sposób uzyskujesz indeksy? Może być lepsze rozwiązanie całej sprawy (np.
Wyrażenia regularne

Odpowiedzi:

207

Ciągi znaków w Pythonie są niezmienne, więc nie można ich traktować jako listy i przypisywać do indeksów.

Użyj .replace()zamiast tego:

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

Jeśli chcesz zamienić tylko niektóre średniki, musisz podać więcej szczegółów. Możesz użyć wycinania, aby wyodrębnić sekcję ciągu do zastąpienia w:

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

Spowoduje to zastąpienie wszystkich średników w pierwszych 10 znakach ciągu.

Martijn Pieters
źródło
Czy to działa w przypadku znaków Unicode? Wydaje mi się, że to nie działa.
Steven2163712
@ Steven2163712: Cały tekst jest w formacie Unicode, więc tak, działa to dobrze ze wszystkimi znakami. Bez konkretnego przykładu nie mogę pomóc w rozwiązaniu konkretnego problemu.
Martijn Pieters
62

Możesz zrobić to poniżej, aby zastąpić dowolny znak odpowiednim znakiem w danym indeksie, jeśli nie chcesz go używać .replace()

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

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

o/p: pythin
Dineshs91
źródło
7
Powinna to być zaakceptowana odpowiedź, bezpośrednio odpowiada na pytanie. To najłatwiejsza metoda, jaką do tej pory znalazłem.
Flare Cat
24

Zamień ciąg w listę; wtedy możesz zmieniać znaki indywidualnie. Następnie możesz złożyć go z powrotem za pomocą .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
źródło
6

Jeśli chcesz zamienić pojedynczy średnik:

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

Havent jednak to przetestował.

Vic
źródło
3
To zadziała (+1), ale jest dość nieefektywne, ponieważ tworzysz nowy ciąg za każdym razem, gdy napotkasz ';'
inspectorG4dget
@ inspectorG4dget, masz rację, to szybkie i brudne - tylko raz - rozwiązanie.
Vic
Właściwie @ inspectorG4dget, czy zaakceptowana odpowiedź nie zawiera tego samego problemu?
Vic
2
line.replace(src,dst)nie. line[:10].replace(src,dst) + line[10:]robi, ale w znacznie mniejszym stopniu. Przypuśćmy line = ';'*12. Twoje rozwiązanie zbuduje nowy ciąg 12 razy. Zaakceptowane rozwiązanie zrobi to raz.
inspectorG4dget
3

Powinno to obejmować nieco bardziej ogólny przypadek, ale powinieneś być w stanie dostosować go do swoich celów

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)

Mam nadzieję że to pomoże

inspectorG4dget
źródło
3

Nie można po prostu przypisać wartości do znaku w ciągu. Użyj tej metody, aby zamienić wartość określonego znaku:

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

Wyjście: In * ia

Ponadto, jeśli chcesz zamienić, powiedz * dla wszystkich wystąpień pierwszego znaku oprócz pierwszego znaku, np. string = gaworzenie wyjście = ba ** le

Kod:

name = "babble"
front= name [0:1]
fromSecondCharacter = name [1:]
back=fromSecondCharacter.replace(front,'*')
return front+back
Darshan Jain
źródło
1

Jeśli zastępujesz wartością indeksu określoną w zmiennej „n”, wypróbuj poniższe rozwiązania:

def missing_char(str, n):
 str=str.replace(str[n],":")
 return str
Bipin Shetty
źródło
1
Problem z tym rozwiązaniem polega na tym, że zastąpiłoby ono wszystkie wystąpienia znaku na pozycji n, a asker chce zastąpić tylko to konkretne wystąpienie
shivram.ss
Dokładnie, kiepskie rozwiązanie!
Erhard Dinhobl,
1

Co powiesz na to:

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
źródło
1

aby efektywnie używać metody .replace () na łańcuchu bez tworzenia oddzielnej listy, na przykład spójrz na listę nazw użytkowników zawierających ciąg znaków z białymi znakami, chcemy zastąpić białe znaki podkreśleniem w każdym z ciągów nazw użytkowników.

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

aby zamienić spacje w każdej nazwie użytkownika, rozważ użycie funkcji zakresu w Pythonie.

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

print(usernames)
N. Samuel
źródło
0

Aby zamienić znak w określonym indeksie, funkcja jest następująca:

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

gdzie s to łańcuch, n to indeks, a c to znak.

Sanket Hire
źródło
0

Napisałem tę metodę, aby zastępować znaki lub zastępować ciągi w określonym przypadku. wystąpienia zaczynają się od 0 (można to łatwo zmienić na 1, jeśli zmienisz opcjonalny argument inst na 1 i zmienną test_instance na 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
źródło
0

Możesz to zrobić:

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
źródło
0

imiona = [„Joey Tribbiani”, „Monica Geller”, „Chandler Bing”, „Phoebe Buffay”]

usernames = []

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

o, p Joey_Tribbiani Monica_Geller Chandler_Bing Phoebe_Buffay

Kasem007
źródło
1
Dzięki, Muhammadzie, jestem początkującym, dam z siebie wszystko.
Kasem007