Replace string chunk between 2 indexes

Asked

Viewed 293 times

3

I have a long string inside a txt file, for example, let’s say my string is about that:

strg = '123456 BANANA 00 SP'

In position 14 and 15 we have the "00", I’m gonna need to replace up front

The logic I’m implementing is:

import re

#abre e começa a leitura do arquivo
arquivo = open('teste.txt','r')
conteudo = arquivo.read()

#verifica se existe a palavra BANANA
if re.search('\\bBANANA\\b', conteudo, re.IGNORECASE):
    print("ACHOU")
    encontrado = True
else:
    print("NÃO ACHOU")
    encontrado = False

#caso o retorno acima seja true, ele substitui a posição 14 e 15 pela string "22"
if encontrado:    
    splt = conteudo.replace(14:15, "22") #o que eu esperava, mas não funciona!
    print(splt)

arquivo = open('teste.txt', 'w')
arquivo.writelines(conteudo)
arquivo.close()

When I get to the part of giving the replace in positions 14:15 by "22", I cannot do, because apparently the method replace just compare the strings and replace it, and that wouldn’t work for me, because on the same line I can have several "00" and it would replace all by "22", but I need it to change only that specific position, it doesn’t guide by a string.

What better way for me to do that replace from a specific position in the string?

2 answers

1


Python, strings are immutable, then there is no way to replace a piece of it. The way is to create another string.

In your case, just take the piece from the beginning of the string to index 13, the new piece that must be placed, and the piece from index 16 onwards, and concatenate them.

Another detail is that its variable encontrado seems redundant to me. If you want to run something only if something is found, do it directly within the first if:

import re

conteudo = '123456 BANANA 00 SP'
if re.search(r'\bBANANA\b', conteudo, re.IGNORECASE):
    print("ACHOU")
    # já faz a substituição aqui mesmo, não precisa da variável "encontrado"
    novo_conteudo = conteudo[:14] + "22" + conteudo[16:]
    print(novo_conteudo) # 123456 BANANA 22 SP
else:
    print("NÃO ACHOU")

I used the syntax of slicing to get the snippets of the string that interest me. In case, conteudo[:14] take from the beginning of the string to index 13 (the final value is not included) and conteudo[16:] take from position 16 to the end of the string.


Generally speaking, to change the index start up to the index end, just do string[:start] + novo_trecho + s[end + 1:]. If you want, do a function to facilitate:

def replace(s, start, end, new):
    return s[:start] + new + s[end + 1:]

if re.search(r'\bBANANA\b', conteudo, re.IGNORECASE):
    print("ACHOU")
    novo_conteudo = replace(conteudo, 14, 15, '22')
    print(novo_conteudo) # 123456 BANANA 22 SP
else:
    print("NÃO ACHOU")

Of course you can improve, including some checks, as: if the indexes do not exceed the size of the string, if start is less than end, etc. But the general idea is this.


Note also that in the regex I used a raw string literal (indicated by r before opening quotes), thus the character \ does not need to be written as \\.

As for the fact that you are reading and writing in the same file, see here a better way to do it.

0

If you’re going to apply several rules, you might want to read line by line.

replace it will replace only the first one it finds, not the entire string. Then you would have to make a loop for it to replace while it exists, which would not be much different from reading the file line by line and that allows you to apply other rules.

If the file has a standard format, you can use the split() and replace the characters in the position you want:

teste.txt

123456 BANANA 00 SP
123456 BANANA 02 RJ
123456 BANANA 03 BH:

python

f = open('teste.txt', 'r')
for line in f:
    data = line.split() #quebra a string em uma lista
    data[2] = "XY" #substitui os caracteres que estão na posição 3
    print('arquivo:', line)
    print('dado alterado:', ' '.join(data))

Browser other questions tagged

You are not signed in. Login or sign up in order to post.