确定错误类型及其在文本中的位置

问题描述 投票:0回答:1

我有一个包含数千行的 Excel 文件,其中包含有关合同履行情况的信息。使用模板将数据加载到系统中。但有时模板填写错误,履行信息行填写错误。

正确的模板如下所示:Object_№_(number)Serviced(dd.mm.YYYY)_Fulfilment_of_obligations_under_agr._№_90/11/122_dated_20.10.2010,_VAT_exempt。

现在我需要检查所有数千个合同描述,并在附加栏中写下发生了什么错误以及包含错误的位置(或在哪个单词之后)。

例如,

原始资料 文字验证
对象 1001 已于 2023 年 11 月 30 日提供服务 履行 agr. 项下的义务。 2010 年 10 月 20 日第 90/11/122 号,免征增值税。 好的
对象 № 10023__已于 2023 年 11 月 30 日提供服务 履行 agr. 下的义务。 2010 年 10 月 20 日第 90/11/122 号,免征增值税。 10023后加倍空格,“№”号后无空格
对象编号 100221 已于 2023 年 11 月 30 日提供服务 履行 agr 项下的义务。 2010 年 10 月 20 日第 90/11/122 号,免增值税 最后没有句号

到目前为止,我只能确定模板是否正确填充以输出信息。使用正则表达式。

template = 'Object № \d+ Serviced (0[1-9]|[12][0-9]|3[01])\.(0[1-9]|1[0-2])\.(20\d\d) Fulfilment of obligations under agr. № 90\/11\/122 dated 20.10.2010, VAT exempt.'

new_col = []
for index, row in df.iterrows():
    if re.match(template, row['original information']):
        new_col.append('OK')
    else:
        new_col.append('not OK')

df = df.assign(text_verification=new_col)
原始资料 文字验证
对象 1001 已于 2023 年 11 月 30 日提供服务 履行 agr. 项下的义务。 2010 年 10 月 20 日第 90/11/122 号,免征增值税。 好的
对象 № 10023__已于 2023 年 11 月 30 日提供服务 履行 agr. 下的义务。 2010 年 10 月 20 日第 90/11/122 号,免征增值税。 不好
对象编号 100221 已于 2023 年 11 月 30 日提供服务 履行 agr 项下的义务。 2010 年 10 月 20 日第 90/11/122 号,免增值税 不好

您能告诉我如何更准确、更简洁地确定文本中的错误类型以及错误位置吗?

python regex text-processing
1个回答
0
投票

稍微阐述一下我自己的评论:您可以自己编写一个解析器并将这些条目视为特定于域的语言(dsa)。我非常喜欢简约的图书馆:

from parsimonious.grammar import Grammar
from parsimonious.nodes import Node, NodeVisitor
from parsimonious.exceptions import ParseError

entries = [
    "Object № 1001 Serviced 30.11.2023 Fulfilment of obligations under agr. № 90/11/122 dated 20.10.2010, VAT exempt.",
    "Object № 10023  Serviced 30.11.2023 Fulfilment of obligations under agr. №90/11/122 dated 20.10.2010, VAT exempt.",
    "Object № 100221 Serviced 30.11.2023 Fulfilment of obligations under agr. № 90/11/122 dated 20.10.2010, VAT exempt"
]

class TemplateVisitor(NodeVisitor):
    grammar = Grammar(
        r"""
        entry           = prefix ws object_no ws serviced ws date ws fulfilment ws obligation_no ws dated ws date vat

        prefix          = "Object №" 
        serviced        = "Serviced"
        fulfilment      = "Fulfilment of obligations under agr. №"
        dated           = "dated"
        vat             = ", VAT exempt."

        object_no       = ~r"\d+"
        date            = ~r"\b\d+\.\d+\.\d+\b"
        obligation_no   = ~r"\b\d+/\d+/\d+\b"
        ws              = ~r"\s"
    """
    )


    def visit_entry(self, node, visited_children):
        """ Makes a dict of the section (as key) and the key/value pairs. """
        return visited_children
    
    def generic_visit(self, node, visited_children):
        """ The generic visit method. """
        return visited_children or node
    


tv = TemplateVisitor()

for entry in entries:
    try:
        ok = tv.parse(entry)
        print("Entry is valid.")
        # everything ok then
    except ParseError as error:
        print("Not ok: ", error)

这会产生

Entry is valid.
Not ok:  Rule 'serviced' didn't match at ' Serviced 30.11.2023' (line 1, column 16).
Not ok:  Rule 'vat' didn't match at ', VAT exempt' (line 1, column 102).

显然,您需要事先检查最常见的错误。

© www.soinside.com 2019 - 2024. All rights reserved.