【发布时间】:2019-11-11 11:27:05
【问题描述】:
使用 iTextSharp v5.5.13
我有大量的 PDF 文件需要解析。其中大约 5% 的人有一张表格,里面有我也需要的数据。
大多数时候我需要的行被解析为2 januari 15 januari € 49,49 € 21,57 € 15,09 € 34,39
我可以使用它。我按空间分割,它可以工作。
但有时月份名称有多余的空格:janu ari
我知道我可以重写策略来摆脱这些额外的空间。我已经将它与 pdf 的其余部分 (ITextExtractionStrategy) 一起使用,但对于此表,我使用的是矩形策略:
var rect = new System.util.RectangleJ(70, 425, 460, 200);
RenderFilter[] filter = { new RegionTextRenderFilter(rect) };
ITextExtractionStrategy strategy =
new FilteredTextRenderListener(new MyLocationTextExtractionStrategy(), filter);
var lines = PdfTextExtractor.GetTextFromPage(reader, pageNumber, strategy).Split('\n');
我的覆盖看起来像这样:
public class MyLocationTextExtractionStrategy : LocationTextExtractionStrategy
{
protected override bool IsChunkAtWordBoundary(TextChunk chunk, TextChunk previousChunk)
{
var dist = chunk.DistanceFromEndOf(previousChunk);
return dist < -chunk.CharSpaceWidth || dist > chunk.CharSpaceWidth / 2.0f;
}
}
我在谷歌上找到了这个。但这并不能解决我的问题。
在janu aridist大于-chunk.CharSpaceWidth的情况下,我不知道下一步该怎么做。
请让我知道什么时候我不应该对这个表使用矩形策略,而是使用不同的方法。
【问题讨论】:
-
蛮力方法怎么样?您是否希望此类表中的数据始终采用这种格式?总是有月份的名字吗?这些是可以预见的。让我们尝试跳出框框思考。你如何去掉所有空格,然后你的字符串变成
2januari15januari€49,49€21,57€15,09€34,39。用正则表达式解析并不难。([0-9]){1,2}(a-z)*([0-9]){1,2}(a-z)*(€[0-9]{1-},[0-9]{2})(€[0-9]{1-},[0-9]{2})(€[0-9]{1-},[0-9]{2})。我没有测试这个正则表达式,我相信它可以进一步完善。 -
感谢@AmedeeVanGasse 建议使用蛮力方法。使用这个正则表达式似乎对我有用:
new Regex(@"([0-9]{1,2})([a-z]*)([0-9]{1,2})([a-z]*)(€[0-9]{1,},[0-9]{2})(€[0-9]{1,},[0-9]{2})(€[0-9]{1,},[0-9]{2})(€[0-9]{1,},[0-9]{2})") -
理论上你可以用
(januari|februari|maart|april|mei|juni|juli|augustus|september|oktober|november|december)捕捉月份,但无论如何,这只是过早的优化,([a-z]*)也可以完成这项工作。 -
我会把我的评论变成答案。 :)