正则表达式忽略html标签

2024-04-25 03:56:06 发布

您现在位置:Python中文网/ 问答频道 /正文

我需要匹配HTML文档文本中的正则表达式。 1) html格式良好,并且 2) 没有不是html标记的“<;>;”符号。 我的问题是,我需要知道原始html文档中匹配项的索引,因为我需要将匹配项转换为原始文档中的链接。这意味着我不能仅仅使用beautiful soup或其他解析器来提取文本。因为解析结果中的匹配项将具有不同的索引。我也不能只在html文档上进行匹配,因为有些标记确实出现在单词的中间,破坏了regex。我需要一种方法: 1) 将已解析文档中匹配项的索引映射到原始文档中的位置,或者, 2) 让我的正则表达式忽略任何标记并继续搜索。你知道吗

我正在使用python re-flavor。 我看到过这个问题:skip over HTML tags in Regular Expression patterns但它是不同的,因为OP希望忽略标记上下文中的空格。那里的答案没有给我一个解决办法。你知道吗

下面是一个(非常简单的)例子。有没有办法匹配:

r'(hello world)'

在字符串中:

string = "<p>hell</p>o world"

在哪里匹配.开始会返回3吗?你知道吗

谢谢!你知道吗


Tags: 文档标记文本ltgt解析器world链接
1条回答
网友
1楼 · 发布于 2024-04-25 03:56:06

好吧,我自己想出了一个解决办法:

import re 

test_html = r'font></font><font face="Tahoma"><font size="4"> alleging that </font></font><font face="Tahoma"><font size="4">soldiers of the Uganda Peoples <span class="scayt-misspell" data-scayt_word="Defence" data-scaytid="32">Defence</span>'


NOT_TAG_REGEX = re.compile(r'(?<=\>)[^<>]+(?=\<)')


def create_chunks(html: str = None):
    """
    Divides an html string into the
    text chunks between tags, while
    storing the start and end indexes of the text
    in both the origional html string, and in the string
    that will be formed by concatenating the text in
    all the chunks.
    """
    matches = NOT_TAG_REGEX.finditer(html)

    text_cursor = 0
    chunks = []
    for match in matches:
        chunk = {
            "text": match.group(),
            "html_start": match.start(),
            "html_end": match.end(),
            "txt_start": text_cursor
        }
        text_cursor += match.end() - match.start()
        chunk["txt_end"] = text_cursor
        chunks.append(chunk)
    return chunks


def to_html_indx(txt_indx, chunks):
    """
    Given the index of a regex match in a string formed from 
    html, returns the index of that same string in the 
    origional html document
    """
    for chunk in chunks:
        if chunk["txt_start"] <= txt_indx <= chunk["txt_end"]:
            txt_indx_in_txt_chunk = txt_indx - chunk["txt_start"]
            html_indx = txt_indx_in_txt_chunk + chunk["html_start"]
            return html_indx
    else:
        print("some error message")
        return None


def main():
    chunks = create_chunks(test_html)
    text = "".join(chunk["text"] for chunk in chunks)
    print(text)
    example_regex = re.compile(r'that soldiers of')
    matches = example_regex.finditer(text)

    for match in matches:
        print("text match: " + match.group())
        txt_start = match.start()
        txt_end = match.end()
        html_start = to_html_indx(txt_start, chunks)
        html_end = to_html_indx(txt_end, chunks)
        print("html match: " + test_html[html_start: html_end])

if __name__ == "__main__":
    main()

这将产生:

text match: that soldiers of

html match: that </font></font><font face="Tahoma"><font size="4">soldiers of

相关问题 更多 >