Одна возможная реализация алгоритма, который я описал в комментариях:
data = '''<p>text1 <ul><li> text2 \(x=1\) </li></ul> text3 \[y=0\]</p> text4 <code>z=e</code>'''
from bs4 import BeautifulSoup
import re
s = re.sub(r'\\\[', r'<bracket1>', data)
s = re.sub(r'\\\]', r'</bracket1>', s)
s = re.sub(r'\\\(', r'<bracket2>', s)
s = re.sub(r'\\\)', r'</bracket2>', s)
soup = BeautifulSoup('<mydata>' + s + '</mydata>', 'html.parser')
for t in soup.select(':not(bracket1):not(bracket2):not(code)'):
for txt in t.find_all(text=True, recursive=False):
if txt.strip():
txt.replace_with("I've changed {}".format(txt))
s = str(soup)
s = re.sub(r'<bracket1>', r'\\[', s)
s = re.sub(r'</bracket1>', r'\\]', s)
s = re.sub(r'<bracket2>', r'\\(', s)
s = re.sub(r'</bracket2>', r'\\)', s)
print('Old data:', data)
print('New data:', ''.join(str(t) for t in BeautifulSoup(s, 'html.parser').mydata.contents))
Отпечатки:
Old data: <p>text1 <ul><li> text2 \(x=1\) </li></ul> text3 \[y=0\]</p> text4 <code>z=e</code>
New data: <p>I've changed text1 <ul><li>I've changed text2 \(x=1\) </li></ul>I've changed text3 \[y=0\]</p>I've changed text4 <code>z=e</code>