【问题标题】:Remove html tags AND get start/end indices of marked-down text?删除 html 标签并获取标记文本的开始/结束索引?
【发布时间】:2015-11-04 08:50:08
【问题描述】:

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

a**b**c

是abc。

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

a<strong>b</strong>c

我知道有很多工具可以转换为纯文本,但我想同时做到这一点,并为每个降价/标签获取内部文本的索引。

例如输入

a<strong>b</strong>c 

将返回两个剥离的文本:

abc

并给我开始(第一个字符(b)的位置)和结束(第一个字符在标记字符串(c)之后的位置),所以对于这个例子(开始,结束)=(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>

【问题讨论】:

    标签: python html tags markdown markup


    【解决方案1】:

    看起来你想要的是一个 HTML 解析器。 HTML Parser 是复杂的东西。因此,您想使用现有的库(创建自己的库很困难,并且在许多边缘情况下可能会失败)。不幸的是,正如this question 中强调的那样,大多数现有的 HTML 解析库不保留位置信息。好消息是,一个可靠地保留位置信息的 HTML 解析器位于 Python 标准库中(请参阅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(): 行。

    【讨论】:

    • 这几乎正是我所需要的!一些事情: - 它似乎忽略了包含其他标签的标签:
        丢失了,每个单词只有一个 标签,应该有多个标签。我想最后将列表和嵌套的上标项目一起存储。 - 如何从整体角色位置获得位置,而不仅仅是每行位置?
    • 解析器只为您提供每行位置信息。如果你想要相对于父标签的位置,那是一个更复杂的野兽。您需要缓存每个标签的位置信息(在handle_starttag 和/或handle_endtag),然后检索它(在handle_data)并使用它来计算文本的相对位置。
    【解决方案2】:

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

    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()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-12
      • 1970-01-01
      • 2016-01-30
      • 2011-06-07
      • 2016-05-24
      • 1970-01-01
      相关资源
      最近更新 更多