如何通过结构识别文本文件格式?

How to identify text file format by its structure?

我有一些文本文件类型,其中包含产品信息、库存、供应商信息等数据,它们的结构各不相同。除了结构本身之外,该类型没有其他标识符(没有 headers、没有文件名约定等)

这些文件的一些示例:

(产品和库存)

2326 | 542212 | Bananas    | 00023 | 1 | pack
2326 | 297875 | Apples     | 00085 | 1 | bag
2326 | 028371 | Pineapple  | 00007 | 1 | can
...

(产品和价格)

12556  Meat, pork        0098.57  
58521  Potatoes, mashed  0005.20     
43663  Chicken wings     0009.99  
...

(产品和供应商 - 这里 N 是分隔符)

03038N92388N9883929
28338N82367N2837912
23002N23829N9339211
...

(产品信息-多行)

VIN|Mom & Pops|78 Haley str. 
PIN|BLT Bagel|5.79|FRESH
LID|0239382|283746
... (repeats this type of info for different products)

还有其他几个。 我想创建一个函数来识别给定文件是这些类型中的哪一种,只使用内容。 Google 没有任何帮助,部分原因是我不知道该使用什么搜索词。不用说,"identify file type by content/structure" 没有任何帮助,它只是给我关于如何查找 jpg、pdf 等的结果。如果我看到其他人为处理类似问题而编写的一些代码,那将会很有帮助。

到目前为止,我的想法是为每种类型制作一个 FileIdentifier class,然后在给定文件时尝试解析它,如果它不起作用,则继续下一种类型。但这对我来说似乎很容易出错,而且我将不得不对大量信息进行硬编码。此外,如果出现另一种格式并且与任何现有格式非常相似,但列中的信息不同,会发生什么情况?

除非您可以限制可能发生的文件格式,否则确实没有放之四海而皆准的答案。您将始终只能找到用于识别格式的启发式方法,除非您可以让设计这些格式的人为其提供唯一标识符,或者您询问用户文件是什么格式。

也就是说,您可以采取一些措施来改善结果,例如确保尝试所有类似格式的实例,然后选择最适合的而不是第一个匹配项。

一般方法总是相同的:尽可能严格地进行每次解码尝试,并且不仅要了解语法,还要了解语义。 IE。如果您知道一个项目只能包含 5 个值之一,或特定范围内的数字,请使用该知识进行检测。另外,不要只是在组件上调用 strtol() 并接受它,检查它是否解析了整个字符串。如果没有,要么就在那里失败,要么保持一个“置信度”值,如果文件有任何可能无效的部分,则降低该值。

然后最后,遍历所有解析结果并选择置信度最高的一个。或者如果你不能,你可以要求用户在最可能的格式之间进行选择。

PS - Unixes 上的文件命令行工具做类似的事情:它查看文件的开头并识别指示特定文件格式的公共序列。