删除 html 标签并获取 start/end 标记文本的索引?

Remove html tags AND get start/end indices of marked-down text?

我有一堆降价格式的文本:

a**b**c

是abc.

我已将其转换为 html 标签以使其更规则:

a<strong>b</strong>c

我知道有很多工具可以转换为纯文本,但我既想这样做,又想为每个 markdown/tag.

获取内部文本的索引

例如输入

a<strong>b</strong>c 

将return两个剥离的文本:

abc

然后给我开始(第一个字符 (b) 的位置)和结束(第一个字符在标记字符串 (c) 之后的位置),所以对于这个例子 (start,end) = (1,2) .这也必须适用于嵌套标签。我知道那里有很多库(我正在使用 Python 3)来删除标签,但我还没有找到一个可以完成这两项任务的库。任何人都可以通过指出执行此操作的方法或描述可能有效的算法来帮助我吗?

嵌套标记示例:

一些标签可以无限嵌套在它们自己的标签类型中

<sup><sup>There</sup></sup> <sup><sup>was</sup></sup> <sup><sup>another</sup></sup> <sup><sup>thread</sup></sup> <sup><sup>like</sup></sup> <sup><sup>this</sup></sup>

还列出了

<ul>
<li>https://steamcommunity.com/tradeoffer/new/partner=30515749&token=WOIxg5eB</li>
<li>79</li>
<li>Why did the elephants get kicked out of the public pool?  THEY KEPT DROPPING THEIR TRUNKS! </li>
</ul>

删除线字体也可以嵌套在斜体等里面

<em><strike>a</strike></em>

这段代码对您来说可能是一个好的开始。希望对你有帮助。

import sys
from html.parser import HTMLParser

line=sys.argv[1]

class MyHTMLParser(HTMLParser):
    stripped_text = ""
    isTag = False
    isData = False
    beginDataIndices = []
    endDataIndices = []
    global_index = 0
    def handle_starttag(self, tag, attrs):
       #print("Encountered a start tag:", tag)
       self.isTag = True
    def handle_endtag(self, tag):
       #print("Encountered an end tag :", tag)
       self.isTag = False
    def handle_data(self, data):
       #print("Encountered some data  :", data)
       self.stripped_text += data
       if(self.isTag):
          self.beginDataIndices.append(self.global_index)
          self.global_index += 1
          self.isData = True
       else:
          if(self.isData):
             self.endDataIndices.append(self.global_index)
          self.isData = False
          self.global_index += 1
    def printIndices(self):
          for i in range(len(self.endDataIndices)):
             print("(%d, %d)" % (self.beginDataIndices[i], self.endDataIndices[i]))

parser = MyHTMLParser()
parser.feed(line)
print(parser.stripped_text)
parser.printIndices()

看起来你想要的是一个 HTML 解析器。 HTML 解析器是复杂的东西。因此,您想使用现有的库(创建自己的库很困难,而且在许多边缘情况下可能会失败)。不幸的是,正如 , most of the existing HTML parsing libraries do not retain position information. The good news is that the one HTML Parser which reliably retains position information is in the Python standard library (see HTMLParser 中突出显示的那样)。当您使用 Python 3 时,该解析器的问题已得到解决。

一个基本示例可能如下所示:

from html.parser import HTMLParser


class StripTextParser(HTMLParser):
    def __init__(self, *args, **kwargs):
        self.data = []
        super(StripTextParser, self).__init__(*args, **kwargs)

    def handle_data(self, data):
        if data.strip():
            # Only use wtrings which are contain more than whitespace
            startpos = self.getpos()
            # `self.getpos()` returns `(line, column)` of start position.
            # Use that plus length of data to calculate end position.
            endpos = (startpos[0], startpos[1] + len(data))
            self.data.append((data, startpos, endpos))


def strip_text(html):
    parser = StripTextParser()
    parser.feed(html)
    return parser.data

test1 = "<sup><sup>There</sup></sup> <sup><sup>was</sup></sup> <sup><sup>another</sup></sup> <sup><sup>thread</sup></sup> <sup><sup>like</sup></sup> <sup><sup>this</sup></sup>" 

print(strip_text(test1))

# Ouputs: [('There', (1, 10), (1, 15)), ('was', (1, 38), (1, 41)), ('another', (1, 64), (1, 71)), ('thread', (1, 94), (1, 100)), ('like', (1, 123), (1, 127)), ('this', (1, 150), (1, 154))]


test2 = """
<ul>
<li>https://steamcommunity.com/tradeoffer/new/partner=30515749&token=WOIxg5eB</li>
<li>79</li>
<li>Why did the elephants get kicked out of the public pool?  THEY KEPT DROPPING THEIR TRUNKS! </li>
</ul>
"""

print(strip_text(test2))

# Outputs: [('https://steamcommunity.com/tradeoffer/new/partner=30515749&token=WOIxg5eB', (3, 4), (3, 77)), ('79', (4, 4), (4, 6)), ('Why did the elephants get kicked out of the public pool?  THEY KEPT DROPPING THEIR TRUNKS! ', (5, 4), (5, 95))]

test3 = "<em><strike>a</strike></em>"

print(strip_text(test3))

# Outputs: [('a', (1, 12), (1, 13))]

没有关于输出所需格式的更多具体信息,我只是创建了一个元组列表。当然,您可以重构以满足您的特定需求。如果您想要所有空格,请删除 if data.strip(): 行。