18
commentary = soup.find('div', {'id' : 'live-text-commentary-wrapper'})
findtoure = commentary.find(text = re.compile('Gnegneri Toure Yaya')).replace('Gnegneri      Toure Yaya', 'Yaya Toure')

Commentary contains various instances of Gnegneri Toure Yaya that need changing to Yaya Toure.

findAll() doesn't work as findtoure is a list.

The other problem I have is this code simply finds them and replaces them into a new variable called findtoure, I need to replace them in the original soup.

I think I am just looking at this from the wrong perspective.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
user2073606
  • 337
  • 1
  • 3
  • 9

1 Answers1

24

You cannot do what you want with just .replace(). From the BeautifulSoup documentation on NavigableString:

You can’t edit a string in place, but you can replace one string with another, using replace_with().

That's exactly what you need to do; take each match, then call .replace() on the contained text and replace the original with that:

findtoure = commentary.find_all(text = re.compile('Gnegneri Toure Yaya'))
for comment in findtoure:
    fixed_text = comment.replace('Gnegneri Toure Yaya', 'Yaya Toure')
    comment.replace_with(fixed_text)

If you want to use these comments further, you'll need to do a new find:

findtoure = commentary.find_all(text = re.compile('Yaya Toure'))

or, if you all you need is the resulting strings (so Python str objects, not NavigableString objects still connected to the BeautifulSoup object), just collect the fixed_text objects:

findtoure = commentary.find_all(text = re.compile('Gnegneri Toure Yaya'))
fixed_comments = []
for comment in findtoure:
    fixed_text = comment.replace('Gnegneri Toure Yaya', 'Yaya Toure')
    comment.replace_with(fixed_text)
    fixed_comments.append(fixed_text)
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343