Как элегантно заменить выделенный текст тега beautifulsoup дочерним тегом, содержащим такой же текст - PullRequest
0 голосов
/ 30 мая 2020

Итак, у меня есть эти теги, как показано ниже, в некоторых случаях содержащие другие теги (в данном случае промежутки)

<p id="p:{659babcd-9de3-0e7a-27ba-7fa0325a40f7}{218}" lang="en-US" style="font-size:10.5pt;margin-top:0pt;margin-bottom:0pt"><span style="font-weight:bold">Test1###yrdy</span></p>,
 <p id="p:{659babcd-9de3-0e7a-27ba-7fa0325a40f7}{220}" lang="en-US" style="font-size:10.5pt;margin-top:0pt;margin-bottom:0pt">Test2###qweqwe</p>,
 <p id="p:{d59b11dc-654f-0d5c-0ee2-f66181a6fa4b}{22}" lang="en-US" style="font-size:10.5pt;margin-top:0pt;margin-bottom:0pt"><span style="color:red">Test3</span> ###qweqeqwe</p>,
 <p id="p:{d59b11dc-654f-0d5c-0ee2-f66181a6fa4b}{17}" lang="en-US" style="font-size:10.5pt;margin-top:0pt;margin-bottom:0pt">Test4 ### sfsfsdfds</p>,
 <p id="p:{d59b11dc-654f-0d5c-0ee2-f66181a6fa4b}{19}" lang="en-US" style="font-size:10.5pt;margin-top:0pt;margin-bottom:0pt">Test5### 121212</p>

Я пытаюсь найти способ заменить то, что идет после ### и ###, на диапазон, содержащий замененный текст
Я смотрю на метод .replace_with (), но он полностью заменит тег

, используя указанное выше против .string, не будет работать, поскольку мои строки:

Test1###yrdy  
Test2###qweqwe  
None  
Test4 ### sfsfsdfds  
Test5### 121212

Таким образом, строка 3 будет пропущена. Я также попытался изменить .contents для p в абзацах:

print(p.contents)
for content in p.contents:
    if "###" in content:
        content=content.replace("###",'<span>'+'###'+'</span>')
print (p.contents)

Вышеупомянутое не повлияло на дерево

Желаемый результат (текст будет заключен в отдельный диапазон с немного стилизации):

<p id="p:{659babcd-9de3-0e7a-27ba-7fa0325a40f7}{218}" lang="en-US" style="font-size:10.5pt;margin-top:0pt;margin-bottom:0pt"><span style="font-weight:bold">Test1<span>###yrdy</span></span></p>,
 <p id="p:{659babcd-9de3-0e7a-27ba-7fa0325a40f7}{220}" lang="en-US" style="font-size:10.5pt;margin-top:0pt;margin-bottom:0pt">Test2<span>###qweqwe</span></p>,
 <p id="p:{d59b11dc-654f-0d5c-0ee2-f66181a6fa4b}{22}" lang="en-US" style="font-size:10.5pt;margin-top:0pt;margin-bottom:0pt"><span style="color:red">Test3</span> <span>###qweqeqwe</span></p>,
 <p id="p:{d59b11dc-654f-0d5c-0ee2-f66181a6fa4b}{17}" lang="en-US" style="font-size:10.5pt;margin-top:0pt;margin-bottom:0pt">Test4 <span>### sfsfsdfds</span></p>,
 <p id="p:{d59b11dc-654f-0d5c-0ee2-f66181a6fa4b}{19}" lang="en-US" style="font-size:10.5pt;margin-top:0pt;margin-bottom:0pt">Test5<span>### 121212</span></p>

1 Ответ

1 голос
/ 30 мая 2020
txt = '''<p id="p:{659babcd-9de3-0e7a-27ba-7fa0325a40f7}{218}" lang="en-US" style="font-size:10.5pt;margin-top:0pt;margin-bottom:0pt"><span style="font-weight:bold">Test1###yrdy</span></p>,
 <p id="p:{659babcd-9de3-0e7a-27ba-7fa0325a40f7}{220}" lang="en-US" style="font-size:10.5pt;margin-top:0pt;margin-bottom:0pt">Test2###qweqwe</p>,
 <p id="p:{d59b11dc-654f-0d5c-0ee2-f66181a6fa4b}{22}" lang="en-US" style="font-size:10.5pt;margin-top:0pt;margin-bottom:0pt"><span style="color:red">Test3</span> ###qweqeqwe</p>,
 <p id="p:{d59b11dc-654f-0d5c-0ee2-f66181a6fa4b}{17}" lang="en-US" style="font-size:10.5pt;margin-top:0pt;margin-bottom:0pt">Test4 ### sfsfsdfds</p>,
 <p id="p:{d59b11dc-654f-0d5c-0ee2-f66181a6fa4b}{19}" lang="en-US" style="font-size:10.5pt;margin-top:0pt;margin-bottom:0pt">Test5### 121212</p>'''

soup = BeautifulSoup(txt, 'html.parser')

r = re.compile(r'(.*?)(###.*)')

for tag in soup.find_all(lambda tag: any('###' in c for c in tag.contents)):
    # find content index:
    for idx, c in enumerate(tag.contents):
        if '###' in c:
            break
    tag.contents[idx] = BeautifulSoup(r.sub(r'\1<span>\2</span>', tag.contents[idx]), 'html.parser')

print(soup)

Печать:

<p id="p:{659babcd-9de3-0e7a-27ba-7fa0325a40f7}{218}" lang="en-US" style="font-size:10.5pt;margin-top:0pt;margin-bottom:0pt"><span style="font-weight:bold">Test1<span>###yrdy</span></span></p>,
 <p id="p:{659babcd-9de3-0e7a-27ba-7fa0325a40f7}{220}" lang="en-US" style="font-size:10.5pt;margin-top:0pt;margin-bottom:0pt">Test2<span>###qweqwe</span></p>,
 <p id="p:{d59b11dc-654f-0d5c-0ee2-f66181a6fa4b}{22}" lang="en-US" style="font-size:10.5pt;margin-top:0pt;margin-bottom:0pt"><span style="color:red">Test3</span> <span>###qweqeqwe</span></p>,
 <p id="p:{d59b11dc-654f-0d5c-0ee2-f66181a6fa4b}{17}" lang="en-US" style="font-size:10.5pt;margin-top:0pt;margin-bottom:0pt">Test4 <span>### sfsfsdfds</span></p>,
 <p id="p:{d59b11dc-654f-0d5c-0ee2-f66181a6fa4b}{19}" lang="en-US" style="font-size:10.5pt;margin-top:0pt;margin-bottom:0pt">Test5<span>### 121212</span></p>
...