正则表达式匹配/中断

Regular expression match / break

我正在对 SEC 文件(例如 10-K)进行文本分析,我拥有的文件是完整的提交文件。完整的提交文件包括 10-K 以及其他几份文件。每个文档都位于标签 ‘<DOCUMENT>’‘</DOCUMENT>’.

我想要的:仅在 ‘</DOCUMENT>’

的第一个实例之前计算 10-K 中的单词数

我想如何实现它:我想使用一个 for 循环,用一个正则表达式 (regex_end10k) 来指示在哪里停止 for 循环。

发生了什么:无论我将正则表达式匹配中断放在哪里,程序都会计算整个文档中的所有单词。我没有错误,但是我得不到想要的结果。

我是怎么知道的:我已经手动修剪了一份文件,同时保留了完整的文件(结果如下)。当我在 ‘</DOCUMENT>’ 的第一个实例之后手动删除不需要的文档时,我减少了大约 750,000 个单词。

Current output

注意:显然我没有足够的 SO 声誉来在我的 post 中嵌入屏幕截图;它默认为 link.

我尝试过的方法:正则表达式匹配中断的几种变体。无论如何,它几乎总是计算整个文档。我相信这两个功能可以在整个文档中执行。我曾尝试将 break 语句放在 get_text_from_html() 中,以便 count_words() 仅在 10-K 上执行,但我没有运气。

下面的代码是一个更大函数的片段。它的目的是 (1) 剥离 html 标签和 (2) 计算文本中的单词数。如果我可以提供任何其他信息,请告诉我,我会更新我的 post.

其余代码(未显示)从标签 ‘<SEC-HEADER>’‘</SEC-HEADER>’ 之间的 header 部分提取公司和报告标识符(例如,“文件”或“cik”) .使用相同的逻辑,在提取 header 信息时,我使用了正则表达式匹配中断逻辑,并且效果很好。我需要帮助来理解为什么当我尝试计算单词数量时同样的逻辑不起作用以及如何更正我的代码。感谢您的帮助。

regex_end10k = re.compile(r'</DOCUMENT>', re.IGNORECASE)

       for line in f:
                
            def get_text_from_html(html:str):
                doc = lxml.html.fromstring(html)
                for table in doc.xpath('.//table'):   # optional: removes tables from HTML source code
                    table.getparent().remove(table)
                for tag in ["a", "p", "div", "br", "h1", "h2", "h3", "h4", "h5"]:
                    for element in doc.findall(tag):
                        if element.text:
                            element.text = element.text + "\n"
                        else:
                            element.text = "\n"
                return doc.text_content() 
            
            
            to_clean = f.read()
            clean = get_text_from_html(to_clean)
            #print(clean[:20000])
            
            def count_words(clean):
                words = re.findall(r"\b[a-zA-Z\'\-]+\b",clean)
                word_count = len(words)
                return word_count

            header_vars["words"] = count_words(clean)
            
            match = regex_end10k.search(line) # This should do it, but it doesn't.
            if match:
                break

你不需要正则表达式,只需拆分你的原始字符串,然后在计算单词之前的部分,上面的简单示例:

text = 'Text before <DOCUMENT> text after'
splited_text = text.split('<DOCUMENT>')
splited_text_before = splited_text[0]
count_words = len(splited_text_before.split())
print(splited_text_before)
print(count_words)

输出

Text before 
2