How to exchange a word between a limit created by two specific points within a string?

Asked

Viewed 45 times

1

Between the word fogo and the word gelo there is a content, and the goal is to change that content by sobrenatural

code:

s = "1 fogo bom dia gelo 2 fogo boa tarde gelo 3 fogo boa noite gelo 4"

s = s.replace('\n\n','\t')
start = 'fogo'
end = 'gelo'

for i in range(len(s)): #1 fogo sobrenatural gelo 2 fogo sobrenatural gelo 3 fogo sobrenatural gelo 4
  if s[i:i+len(start)] == start:
    for j in range(i+len(start), len(s)):
      if s[j:j+len(end)] == end:
        g = s[i + len(start):j]
        v=s.replace(g,' sobrenatural ')
        print(v)
        break

The print as it goes:

1 fogo sobrenatural gelo 2 fogo boa tarde gelo 3 fogo boa noite gelo 4
1 fogo bom dia gelo 2 fogo sobrenatural gelo 3 fogo boa noite gelo 4
1 fogo bom dia gelo 2 fogo boa tarde gelo 3 fogo sobrenatural gelo 4

The correct print would be:

1 fogo sobrenatural gelo 2 fogo sobrenatural gelo 3 fogo sobrenatural gelo 4

1 answer

2


Edit:
As we remember comments by the user hkotsubo the standard has been added \b which corresponds to an empty string attached to the beginning and end of the pattern determining a formal limit of the word to be matched thus avoiding the capture of "Botafogo .... Gelol", "fires ... froze",...

Instead of rummaging through a string, in a set of loops, character by character searching for bounding strings and then substituting into an error-prone activity. Replace a character set delimited by two specific words using regular expressions, which in Python are used through module re.

In your specific case, a string delimited by words fogo and gelo, can be done with matching pattern (?<=\bfogo\b).+?(?=\bgelo\b), where:

  • (?<=\bfogo\b): matching pattern lookbehind. Matches only if the string is preceded by the string fogo.
  • .+? : corresponds to one or more characters in any greedy way, or will make the least possible correspondence.
  • (?=\bgelo\b): matching pattern Lookahead. Matches only if the string is followed by the string gelo.

To make the substitution can be used the method re.sub(pattern, repl, string, count=0, flags=0). In this case the example used the flag re.IGNORECASE that does the matching by not differentiating between upper and lower case:

import re

s = "1 fogo bom dia gelo 2 fogo boa tarde gelo 3 fogo boa noite gelo 4"

p = r'(?<=\bfogo\b).+?(?=\bgelo\b)'                       #Determina o padrão de captura.

r = re.sub(p, " sobrenatural ", s, flags=re.IGNORECASE)  #Faz capturas e substituições.

print(r)                                                 
# 1 fogo sobrenatural gelo 2 fogo sobrenatural gelo 3 fogo sobrenatural gelo 4

Test in Repl.it

  • 1

    I would just add the \b to avoid cases like "Botafogo etc gelol", "fires etc froze", etc - it was not clear if it is to treat these cases, but anyway...

Browser other questions tagged

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