Найти и вставить теги с помощью регулярного выражения

Я конвертирую книгу из PDF в epub в калибре. Но заголовки не находятся внутри тегов заголовков, поэтому попробуйте функцию python, используя регулярное выражение для ее замены.

пример текста:

<p class="calibre1"><a id="p1"></a>Chapter 370: Slamming straight on</p>
<p class="softbreak"> </p>
<p class="calibre1">Hearing Yan Zhaoge’s suggestion, the Jade Sea City martial practitioners here were all stunned.</p>
<p class="calibre1"><a id="p7"></a>Chapter 372: Yan Zhaoge’s plan</p>
<p class="softbreak"> </p>
<p class="calibre1">Yan Zhaoge and Ah Hu sat on Pan-Pan’s back, black water swirling about Pan-Pan’s entire body, keeping away the seawater as he shot forward at lightning speed.</p>

я пытался использовать регулярное выражение с

def replace(match, number, file_name, metadata, dictionaries, data, functions, *args, **kwargs):
    
    pattern = r"</a>(?i)chapter [0-9]+: [\w\s]+(.*)<br>"
    list = re.findall(pattern, match.group())
    
    for x in list:
        x = "</a>(?i)chapter [0-9]+: [\w\s]+(.?)<br>"
        x = s.split("</a>", 1)[0] + '</a><h2>' + s.split("a>",1)[1]
        x = s.split("<br>", 1)[0] + '</h2><br>' + s.split("<br>",1)[1]
    return match.group()

а также


def replace(match, number, file_name, metadata, dictionaries, data, functions, *args, **kwargs):
    pattern = r"</a>(?i)chapter [0-9]+: [\w\s]+(.*)<br>"
    s.replace(re.match(pattern, s), r'<h2>$0')

Но так и не получил ожидаемого результата. то, что я хочу, это...

Вход

</a>Chapter 370: Slamming straight on</p>

Выход

</a><h2>Chapter 370: Slamming straight on</h2></p>

Тег h2 должен быть добавлен во всех подобных экземплярах


person Andruraj    schedule 17.06.2019    source источник
comment
вместо этого вам, вероятно, следует использовать синтаксический анализатор xml. не анализировать xml с регулярным выражением   -  person Jean-François Fabre    schedule 17.06.2019
comment
volarenovels.com/novel/historys-strongest-senior-brother? T&C не позволяют изменять их содержание   -  person Patrick Artner    schedule 17.06.2019
comment
Я не изменяю какой-либо контент, я конвертирую в epub для чтения на мобильных устройствах, и мне, как программисту, интересно узнать, как это сделать.   -  person Andruraj    schedule 18.06.2019


Ответы (2)


regex нельзя использовать для разбора xml. См.: Почему невозможно использовать регулярное выражение для анализа HTML/XML: формальное объяснение с точки зрения непрофессионала (Why shouldn't you..было бы лучше заглавие)

Однако вместо этого вы можете использовать BeautifulSoup:

from bs4 import BeautifulSoup
data = """<p class="calibre1"><a id="p1"></a>Chapter 370: Slamming straight on</p>
<p class="softbreak"> </p>
<p class="calibre1">Hearing Yan Zhaoge’s suggestion, the Jade Sea City martial practitioners here were all stunned.</p>
<p class="calibre1"><a id="p7"></a>Chapter 372: Yan Zhaoge’s plan</p>
<p class="softbreak"> </p>
<p class="calibre1">Yan Zhaoge and Ah Hu sat on Pan-Pan’s back, black water swirling about Pan-Pan’s entire body, keeping away the seawater as he shot forward at lightning speed.</p>
i t"""

soup = BeautifulSoup(data, 'lxml')


for x in soup.find_all('p', {'class':'calibre1'}):

    link = x.find('a')
    title = x.text
    corrected_title = soup.new_tag('h2')
    corrected_title.append(title)

    if link:
        x.string=''
        corrected_title = soup.new_tag('h2')
        corrected_title.append(title)
        link.append(corrected_title)
        x.append(link)

print(soup.body)

Вывод

<body>
    <p class="calibre1">
        <a id="p1">
            <h2>Chapter 370: Slamming straight on</h2>
        </a>
    </p>
    <p class="softbreak"> </p>
    <p class="calibre1">Hearing Yan Zhaoge’s suggestion, the Jade Sea City martial practitioners here were all stunned.</p>
    <p class="calibre1">
        <a id="p7">
            <h2>Chapter 372: Yan Zhaoge’s plan</h2>
        </a>
    </p>
    <p class="softbreak"> </p>
    <p class="calibre1">Yan Zhaoge and Ah Hu sat on Pan-Pan’s back, black water swirling about Pan-Pan’s entire body, keeping away the seawater as he shot forward at lightning speed.</p>
    i t
</body>
person Sebastien D    schedule 17.06.2019
comment
Спасибо @Sebastien, но, к сожалению, разрешает только регулярное выражение. И это тоже не работает. - person Andruraj; 18.06.2019
comment
@Andruraj, мой позор, я исправил это. Просто любопытно, почему работает только regex? - person Sebastien D; 18.06.2019
comment
Я использую калибр для преобразования pdf в epub, и это позволяет использовать только регулярное выражение. Надеюсь, это достаточно проясняет. - person Andruraj; 27.06.2019

Комментарий Jean-François было бы гораздо лучше следовать, но если бы мы могли to, я предполагаю, что мы бы начали с этого выражения:

(<\/a>)([^<]+)?(<\/p>)
(<\/a>)(chapter\s+[0-9]+[^<]+)?(<\/p>)

заменяется на:

\1<h2>\2</h2>\3

Демонстрация 1

Демонстрация 2

Тест

# coding=utf8
# the above tag defines encoding for this document and is for Python 2.x compatibility

import re

regex = r"(<\/a>)(chapter\s+[0-9]+[^<]+)?(<\/p>)"

test_str = ("<p class=\"calibre1\"><a id=\"p1\"></a>Chapter 370: Slamming straight on</p>\n"
    "<p class=\"softbreak\"> </p>\n"
    "<p class=\"calibre1\">Hearing Yan Zhaoge’s suggestion, the Jade Sea City martial practitioners here were all stunned.</p>\n"
    "<p class=\"calibre1\"><a id=\"p7\"></a>Chapter 372: Yan Zhaoge’s plan</p>\n"
    "<p class=\"softbreak\"> </p>\n"
    "<p class=\"calibre1\">Yan Zhaoge and Ah Hu sat on Pan-Pan’s back, black water swirling about Pan-Pan’s entire body, keeping away the seawater as he shot forward at lightning speed.</p>")

subst = "\\1<h2>\\2</h2>\\3"

# You can manually specify the number of replacements by changing the 4th argument
result = re.sub(regex, subst, test_str, 0, re.MULTILINE | re.IGNORECASE)

if result:
    print (result)

# Note: for Python 2.7 compatibility, use ur"" to prefix the regex and u"" to prefix the test string and substitution.
person Emma    schedule 17.06.2019
comment
Спасибо @Эмма. Но он также обнаруживает теги ‹/a›‹/p› (для обоих регулярных выражений) - person Andruraj; 18.06.2019