用空格覆盖每个 HTML 标签,这样每个文本字符的位置就不会移动

Overwrite each HTML tag with spaces so the position of each text character doesn’t shift

在 python 中,我想用空格覆盖每个 HTML 标签,这样字符串中每个文本字符的位置就不会移动。

例如 <p> 将替换为三个空格 .

以下是我为实现目标而编写的代码的最佳尝试,但对于这样一个简单的任务来说感觉太脆弱和复杂了:

from html.parser import HTMLParser

class MyHTMLParser(HTMLParser):
    def __init__(self):
        self.html_redacted_with_whitespaces = ""
        HTMLParser.__init__(self)
        
    def handle_starttag(self, tag, attrs):
        self.html_redacted_with_whitespaces +=  " " * (len(tag) + 2)
        
    def handle_endtag(self, tag):
        self.html_redacted_with_whitespaces +=  " " * (len(tag) + 3)
        
    def handle_data(self, data):
        self.html_redacted_with_whitespaces +=  data
        
parser = MyHTMLParser()
test_html = """<html><head><title>Test</title></head>
<body><h1>Replace my tags with spaces!</h1></body></html>"""
parser.feed(test_html)

len(test_html), len(parser.html_redacted_with_whitespaces)
print(test_html)
print(parser.html_redacted_with_whitespaces)

输出:

<html><head><title>Test</title></head>
<body><h1>Replace my tags with spaces!</h1></body></html>
                   Test               
          Replace my tags with spaces!   

我的目标是在将其输入 spacy 之前用空格编辑 html。
有必要在将其输入 spacy 之前编辑 html,这样 html 标签就会“混淆”nlp 模型。
此问题在以下部分讨论:https://github.com/explosion/spaCy/issues/4177

我想保持间距不变的原因是能够使用 spacy 的 NER doc.ents 来突出显示。后来在 post-processing 中,我在原始 html.

中注入了自己的标签

我四处搜索但找不到交钥匙解决方案。

您可以使用基于正则表达式的替换,这允许回调知道哪个将是替换文本:

import re

test_html = """<html><head><title>Test</title></head>
<body><h1>Replace my tags with spaces!</h1></body></html>"""


filtered_text = re.sub("<.*?>",lambda m: " " * len(m.group(0))   , test_html)

回调为每个匹配传递一个正则表达式“匹配”对象,它有一个“组”方法,returns 正则表达式中每个匹配组的字符串,然后我们使用它的 len.

正则表达式本身很简单,而且有点幼稚:它只是寻找任何 < 和下一个。 > - 如果对它们使用任何转义(如在 <script><cdata> 或注释标签内),它根本不起作用。