1.简介

构造数据类型PdfString封装Rect类,PdfAnalyzer类中定义一些PDF解析方法。

2.PdfString类与Rect类

public class PdfString : IComparable<PdfString>
{
public string Words { get; set; }
public Rect Position { get; set; }
public int PageNumber { get; set; } public PdfString(string str, Rect pos, int pageNum)
{
this.Words = str;
this.Position = pos;
this.PageNumber = pageNum;
} public override string ToString()
{
return this.Words;
} public static PdfStringComparer GetComparer()
{
return new PdfString.PdfStringComparer();
} public int CompareTo(PdfString rhs)
{
return this.Position.x2.CompareTo(rhs.Position.x2);
} /// <summary>
///comparer by Horizontal or vertical
/// </summary>
/// <param name="rhs"></param>
/// <param name="which">comparer type</param>
/// <returns></returns>
public int CompareTo(PdfString rhs, PdfString.PdfStringComparer.ComparisonType which)
{
switch (which)
{
case PdfStringComparer.ComparisonType.Horizontal:
return this.Position.x2.CompareTo(rhs.Position.x2);
case PdfStringComparer.ComparisonType.Vertical:
return this.Position.y2.CompareTo(rhs.Position.y2);
} return ;
} /// <summary>
/// for comparer custom comparer type
/// </summary>
public class PdfStringComparer : IComparer<PdfString>
{
private PdfString.PdfStringComparer.ComparisonType whichComparison; public enum ComparisonType { Horizontal, Vertical }; public int Compare(PdfString lhs, PdfString rhs)
{
return lhs.CompareTo(rhs, whichComparison);
} public PdfString.PdfStringComparer.ComparisonType WhichComparison
{
get { return whichComparison; }
set { whichComparison = value; }
}
}
}
public class Rect
{
public Rect();
public Rect(Obj rect);
public Rect(double x1, double y1, double x2, double y2); public double x1 { get; set; }
public double x2 { get; set; }
public double y1 { get; set; }
public double y2 { get; set; } public void __dtor();
public void Attach(Obj obj);
public bool Contains(double x, double y);
public void Get(ref double out_x1, ref double out_y1, ref double out_x2, ref double out_y2);
public double Height();
public void Inflate(double amount);
public void Inflate(double x, double y);
public bool IntersectRect(Rect rect1, Rect rect2);
public void Normalize();
public static Rect op_Assign(Rect lr, Rect rr);
public void Set(Rect p);
public void Set(double x1, double y1, double x2, double y2);
public bool Update();
public bool Update(Obj obj);
public double Width();
}

3.关于PdfString类

1.封装Rect原因

a.Rect这个类粒度太小,必须有个类能够保存搜索到关键信息的数据结构,为了根据语义二次识别出准备关键信息。

b. Words属性保存每个搜索结果值

c.Rect:保存结果左上角坐标(x1,y1)右下角坐标(x2,y2)信息

d.PageNumber:数据所在页码,由于PDF中坐标相对于每一页来说的,所以需要页码定位数据为止。

2.实现IComparable<PdfString>接口和加入一个嵌入类PdfStringComparer

a.因为在根据坐标解析PDF中获取数据信息并不是有序,就是说抓取数据并不是按照一定规律保存的,而是杂乱无章的。

b.如果单纯实现IComparable<T>接口可以根据Position属性选择一种方式来讲得到结果集排序,注意实现IComparable<T>

只能选择一种固定排序方式,无法根据情况自定义排序方式,于是PdfString类中引入一个嵌入类PdfStringComparer当使用

x1或x2坐标作为基准则按Horizontal位置坐标排序结果集,反之按照Vertical。

4.关于PdfAnalyzer类

public enum PositionRect { X1, Y1, X2, Y2 }

public class PdfAnalyzer
{
public List<PdfString> RegexSearchAllPages(PDFDoc doc, string pattern)
{
return RegexSearch(doc, pattern, false, -, -, true);
} public List<PdfString> RegexSearchByPageRange(PDFDoc doc, string pattern, int startPage, int endPage)
{
if (endPage > doc.GetPageCount())
throw new Exception("endPage out of MaxRange of pdf."); if (startPage < )
throw new Exception("startPage out of MixRange of pdf."); if (startPage > endPage)
throw new Exception("pageRange is invalid."); return RegexSearch(doc, pattern, false, startPage, endPage, true);
} public List<PdfString> RegexSearchByPage(PDFDoc doc, string pattern, int pageIndex)
{
if (pageIndex > doc.GetPageCount())
throw new Exception("pageIndex out of MaxRange of pdf."); if (pageIndex < )
throw new Exception("pageIndex out of MixRange of pdf."); return RegexSearch(doc, pattern, false, pageIndex, pageIndex, true);
} public List<PdfString> RegexSearch(PDFDoc doc, string pattern, bool ifWholeWord, int startPage, int endPage, bool ignoreCase)
{
List<PdfString> result = new List<PdfString>();
Int32 page_num = ;
string result_str = "";
string ambient_string = "";
Highlights hlts = new Highlights(); Int32 mode = (Int32)(TextSearch.SearchMode.e_reg_expression | TextSearch.SearchMode.e_highlight);
if (ifWholeWord) mode |= (Int32)TextSearch.SearchMode.e_whole_word;
if (ignoreCase) mode |= (Int32)TextSearch.SearchMode.e_case_sensitive; int pageCount = doc.GetPageCount();
if (endPage > pageCount) endPage = pageCount; TextSearch txt_search = new TextSearch();
txt_search.Begin(doc, pattern, mode, startPage, endPage); while (true)
{
TextSearch.ResultCode code = txt_search.Run(ref page_num, ref result_str, ref ambient_string, hlts); if (code == TextSearch.ResultCode.e_found)
{
hlts.Begin(doc);
double[] box = null;
string temp = result_str; while (hlts.HasNext())
{
box = hlts.GetCurrentQuads();
if (box.Length != )
{
hlts.Next();
continue;
} result.Add(new PdfString(result_str, new Rect(box[], box[], box[], box[]), page_num));
hlts.Next();
}
}
else if (code == TextSearch.ResultCode.e_done)
{
break;
}
} return result;
} public List<PdfString> RegexExtractByPositionWithPage(PDFDoc doc, string pattern, int pageIndex, Rect rect, PositionRect positionRect = PositionRect.Y2, double range = 2.0)
{
return GetNearbyPdfString(RegexSearchByPage(doc, pattern, pageIndex), rect, positionRect, range);
} public List<PdfString> GetNearbyPdfString(List<PdfString> pdfStringAll, Rect rect, PositionRect positionRect, double range)
{
List<PdfString> pdfStringFilter = new List<PdfString>(); foreach (var pdf in pdfStringAll)
{
if (pdf == null)
continue; if (GetRange(pdf.Position, rect, positionRect) > range)
continue; pdfStringFilter.Add(pdf);
} PdfString.PdfStringComparer comparerType = PdfString.GetComparer(); if (positionRect.Equals(PositionRect.Y2) || positionRect.Equals(PositionRect.Y1))
comparerType.WhichComparison = PdfString.PdfStringComparer.ComparisonType.Horizontal;
else if (positionRect.Equals(PositionRect.X1) || positionRect.Equals(PositionRect.X2))
comparerType.WhichComparison = PdfString.PdfStringComparer.ComparisonType.Vertical; pdfStringFilter.Sort(comparerType); return pdfStringFilter;
} private double GetRange(Rect pdf, Rect title, PositionRect positionRect)
{
switch (positionRect)
{
case PositionRect.X1:
return Math.Abs(pdf.x1 - title.x1);
case PositionRect.X2:
return Math.Abs(pdf.x2 - title.x2);
case PositionRect.Y1:
return Math.Abs(pdf.y1 - title.y1);
case PositionRect.Y2:
return Math.Abs(pdf.y2 - title.y2);
default:
throw new Exception("calculation range of pdfstring with title error.");
}
} public List<PdfString> RegexExtractByPositionWithAllPage(PDFDoc doc, string pattern, Rect rect, PositionRect positionRect = PositionRect.Y2, double range = 2.0)
{
return GetNearbyPdfString(RegexSearchAllPages(doc, pattern), rect, positionRect, range);
} public List<PdfString> RegexExtractByPositionWithRangePage(PDFDoc doc, string pattern, int startPage, int endPage, Rect rect, PositionRect positionRect = PositionRect.Y2, double range = 2.0)
{
return GetNearbyPdfString(RegexSearchByPageRange(doc, pattern, startPage, endPage), rect, positionRect, range);
}
}

注释:

1.RegexSearchAllPages、RegexSearchByPageRange、RegexSearchByPage由方法名可知通过正则表达式得到搜索的 PdfString结果集合。

2.RegexExtractByPositionWithPage、RegexExtractByPositionWithAllPage、RegexExtractByPositionWithRangePage由方法名只知根据传入坐标和误差范围或者每一行或者每列的排序后数据集合。

PDF数据提取------2.相关类介绍的更多相关文章

  1. PDF数据提取------3.解析Demo

    1.PDF中文本字符串格式中关键值信息抓取(已完成) 简介:这种解析比较传统最简单主要熟练使用Regular Expression做语义识别和验证.例如抓取下面红色圈内关键信息 string mett ...

  2. 大数据及hadoop相关知识介绍

    一.大数据的基本概念 1.1什么是大数据 互联网企业是最早收集大数据的行业,最典型的代表就是Google和百度,这两个公司是做搜索引擎的,数量都非常庞大,每天都要去把互联网上的各种各样的网页信息抓取下 ...

  3. I/O---BufferedInputStream及相关类介绍

    关于BufferedInputStream 是java提供的具有缓存作用的字节输入流.与之对应的还有BufferedOutStream 和 BufferedRead 和BufferedWriter 这 ...

  4. scrapy架构与目录介绍、scrapy解析数据、配置相关、全站爬取cnblogs数据、存储数据、爬虫中间件、加代理、加header、集成selenium

    今日内容概要 scrapy架构和目录介绍 scrapy解析数据 setting中相关配置 全站爬取cnblgos文章 存储数据 爬虫中间件和下载中间件 加代理,加header,集成selenium 内 ...

  5. Util应用程序框架公共操作类(一):数据类型转换公共操作类(介绍篇)

    本系列文章将介绍一些对初学者有帮助的辅助类,这些辅助类本身并没有什么稀奇之处,如何能发现需要封装它们可能更加重要,所谓授之以鱼不如授之以渔,掌握封装公共操作类的技巧才是关键,我会详细说明创建这些类的动 ...

  6. VS2010/MFC编程入门之十三(对话框:属性页对话框及相关类的介绍)

    前面讲了模态对话框和非模态对话框,本节开始鸡啄米讲一种特殊的对话框--属性页对话框.另外,本套教程所讲大部分对VC++各个版本均可适用或者稍作修改即可,但考虑到终究还是基于VS2010版本的,所以将& ...

  7. VS2010-MFC(对话框:属性页对话框及相关类的介绍)

    转自:http://www.jizhuomi.com/software/164.html 一 属性页对话框的分类 属性页对话框想必大家并不陌生,XP系统中桌面右键点属性,弹出的就是属性页对话框,它通过 ...

  8. MFC编程入门之十三(对话框:属性页对话框及相关类的介绍)

    前面讲了模态对话框和非模态对话框,本节来将一种特殊的对话框--属性页对话框. 属性页对话框的分类 属性页对话框想必大家并不陌生,XP系统中桌面右键点属性,弹出的就是属性页对话框,它通过标签切换各个页面 ...

  9. SQL Server数据库读取数据的DateReader类及其相关类

    之前学了几天的SQL Server,现在用C#代码连接数据库了. 需要使用C#代码连接数据库,读取数据. 涉及的类有: ConfigurationManage SqlConnection SqlCom ...

随机推荐

  1. jQuery RemoveAttr(checked)之后再Attr(checked)属性无效果的原因分析

    jQuery中attr()和prop()在修改checked属性时的区别 投稿:whsnow 字体:[增加 减小] 类型:转载   使用语句$.attr('checked',true),将复选框的属性 ...

  2. CentOS如何开启ssh远程连接

    假设VPS采用centos,再假设用较新版本6.5. VPS上可能没有安装桌面,但一般来说都会安装ssh,并且防火墙默认开放22端口. 那就从ssh开始. # 安装ssh,默认已安装好 # yum i ...

  3. C# 数组、一维数组、二维数组、多维数组、锯齿数组

    C#  数组.一维数组.二维数组.多维数组.锯齿数组 一.数组: 如果需要使用同一类型的对象,就可以使用数组,数组是一种数据结构,它可以包含同一类型的多个元素.它的长度是固定的,如长度未知的情况下,请 ...

  4. PostgreSQL的创建表

    PostgreSQL的CREATE TABLE语句是用来在任何指定的的数据库中创建一个新表. 语法 CREATE TABLE语句的基本语法如下: CREATE TABLE table_name( co ...

  5. mysql 语句大全

    1.说明:创建数据库 CREATE DATABASE database-name 2.说明:删除数据库 drop database dbname 3.说明:备份sql server --- 创建 备份 ...

  6. [HIHO1082]然而沼跃鱼早就看穿了一切(字符串水题)

    题目链接:http://hihocoder.com/problemset/problem/1082 数据范围小,胡搞. /* ━━━━━┒ギリギリ♂ eye! ┓┏┓┏┓┃キリキリ♂ mind! ┛┗ ...

  7. leetcode:Delete Node in a Linked List

    Write a function to delete a node (except the tail) in a singly linked list, given only access to th ...

  8. C# 正则 获取 Img Src路径

    string str = "<form id=\"form1\" runat=\"server\"><div><p> ...

  9. 第五讲:深入hibernate的三种状态

    学过hibernate的人都可能都知道hibernate有三种状态,transient(瞬时状态),persistent(持久化状态)以及detached(离线状态),大家伙也许也知道这三者之间的区别 ...

  10. open_binary_frm

    参数uchar* head 是已经分配好内存的64个字节的地址 http://mysql.taobao.org/monthly/2015/08/07/ /** *先从.frm文件读取64字节 *第28 ...