【问题标题】:how can i count the number of words between 2 predefined words?我如何计算 2 个预定义单词之间的单词数?
【发布时间】:2018-03-25 09:33:50
【问题描述】:

<replace-add>that I don't know you know cause</replace-add>that I can help you with <replace-del>oh</replace-del> <replace-add>us</replace-add>谢谢,所以我只是安排了一个旅程<replace-del>for@987654328 @@<replace-add>from</replace-add>我的女儿<replace-del>tenah Dyer</replace-del><replace-add>clear dire</replace-add>

如何计算文本中<replace-add></replace-add> 之间的确切字数。

【问题讨论】:

  • 您的意思是指在这些标签之间出现的所有以空格分隔的字符运行吗?为了清楚起见,您能否包括预期的样本输出?另外,尝试缩进四个空格来格式化代码。我们可以假设标签会完全一样地出现,或者它们可以有属性吗?
  • 我不知道你知道原因 输出将是 7,还要注意我在文本中会有其他标签,如 等等。但是 上的例子就足够了。

标签: python html python-2.7 beautifulsoup


【解决方案1】:

不使用任何库:

def get_tag_indexes(text, tag, start_tag):
    tag_indexes = []
    start_index = -1

    while True:
        start_index = text.find(tag, start_index + 1)

        if start_index != -1:
            if start_tag:
                tag_indexes.append(start_index + len(tag))
            else:
                tag_indexes.append(start_index)
        else:
            return tag_indexes

text = """<replace-add>that i dont know you know cause</replace-add> i could help you with <replace-del>that oh</replace-del> <replace-add>us</replace-add> thanks so i just set up a ride <replace-del>for</replace-del> <replace-add>from</replace-add> my daughter <replace-del>tenah dyer</replace-del> <replace-add>clear dire</replace-add>"""

tag_starts = get_tag_indexes(text, "<replace-add>", True)
tag_ends = get_tag_indexes(text, "</replace-add>", False)

for start, end in zip(tag_starts, tag_ends):
    words = text[start:end].split()
    print "{} words - {}".format(len(words), words)

给你:

7 words - ['that', 'i', 'dont', 'know', 'you', 'know', 'cause']
1 words - ['us']
1 words - ['from']
2 words - ['clear', 'dire']

这使用一个函数来返回任何给定文本的位置列表。然后可以使用它来提取两个标签之间的文本。


作为一种替代方法,这实际上也可以使用 beautifulsoup 来完成:

from bs4 import BeautifulSoup

text = """<replace-add>that i dont know you know cause</replace-add> i could help you with <replace-del>that oh</replace-del> <replace-add>us</replace-add> thanks so i just set up a ride <replace-del>for</replace-del> <replace-add>from</replace-add> my daughter <replace-del>tenah dyer</replace-del> <replace-add>clear dire</replace-add>"""
soup = BeautifulSoup(text, "lxml")

for block in soup.find_all('replace-add'):
    words = block.text.split()
    print "{} words - {}".format(len(words), words)

【讨论】:

  • 嘿马丁,我不应该导入任何库。
  • @Tim 根本没有?!你允许标准库的东西吗?这是作业的要求还是什么?
  • 我的意思是它们可以像 import os 、 difflib 等一样使用,但最好不要使用它们,除非它们是必不可少的并且不是任务。
  • @Tim 这有什么原因吗? Python 的标准库是它最好的东西之一。您是否可能是说您宁愿不使用标准库中没有的额外包?我有点困惑..
【解决方案2】:

根据来源的可信度,您可以做两件事。鉴于此

source = """<replace-add>that i dont know you know cause</replace-add> i could help you with <replace-del>that oh</replace-del> <replace-add>us</replace-add> thanks so i just set up a ride <replace-del>for</replace-del> <replace-add>from</replace-add> my daughter <replace-del>tenah dyer</replace-del> <replace-add>clear dire</replace-add>"""

你可以像这样使用正则表达式:

import re

from itertools import chain

word_pattern = re.compile(r"(?<=<replace-add>).*?(?=</replace-add>)")
re_words = list(chain.from_iterable(map(str.split, word_pattern.findall(source))))

这只有在源与这些标签完全匹配且没有属性等情况下才有效。

标准库中的另一个选项是 HTML 解析:

from html.parser import HTMLParser

class MyParser(HTMLParser):
    def get_words(self, html):
        self.read_words = False
        self.words = []
        self.feed(html)
        return self.words

    def handle_starttag(self, tag, attrs):
        if tag == "replace-add":
            self.read_words = True

    def handle_data(self, data):
        if self.read_words:
            self.words.extend(data.split())

    def handle_endtag(self, tag):
        if tag == "replace-add":
            self.read_words = False


parser = MyParser()
html_words = parser.get_words(source)

这种方法会更可靠,并且可能会更有效,因为它使用完全专注于这项任务的工具。

现在,做

print(re_words)
print(html_words)

我们得到

['that', 'i', 'dont', 'know', 'you', 'know', 'cause', 'us', 'from', 'clear', 'dire']
['that', 'i', 'dont', 'know', 'you', 'know', 'cause', 'us', 'from', 'clear', 'dire']

(当然,这个列表的len是字数。)

如果您严格要求字数,您可以只保留一个运行总和,并将遇到的每个数据的 data.split 的长度添加到该总和中。

如果您真的无法进行任何导入,您将不得不做出一些牺牲,或者必须实现自己的正则表达式引擎/html 解析器。如果这是家庭作业的要求,那么您确实应该在发布问题之前表现出一些努力。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-09
    相关资源
    最近更新 更多