/// <summary> /// Construye una instancia de la clase TextBoundMatch /// a partir de una coincidencia anterior. /// </summary> /// <param name="parserMatch">Coincidencia anterior.</param> public TextBoundMatch(ITextMatch parserMatch) { _ParserMatch = parserMatch; _MatchToken = _ParserMatch.GetRegexMatch(); _MatchLowerFirst = GetLowerFirst(); _MatchLowerSecond = GetLowerSecond(); _MatchUpper = GetUpper(); UseLengthOnPatternDigitReplacement = true; }
/// <summary> /// Construye una nueva instancia de la clase PdfCompareInfo. /// </summary> /// <param name="pdf">Instacia de la clase PdfUnstructuredDoc /// que se utilizó para la comparación a la que pertenence /// el info.</param> /// <param name="pdfPage">Instancia de la clase PdfUnstructuredPage /// de la colección PdfUnstructuredPages del pdf, sobre /// la que se obtuvo el resultado contenido en el /// info a crear.</param> /// <param name="pdfTextRectangle">PdfTextRectangle sobre el que /// se ha obetnido el resultado contenido en el info.</param> /// <param name="textParserMatch">ITextParserMatch orígen del info.</param> /// <param name="propertyInfo">PropetyInfo de la propiedad /// de los metadatos de la cual se a comparado el valor y se /// ha obtenido la coincidencia que ha generado el info.</param> public PdfCompareInfo(PdfUnstructuredDoc pdf, PdfUnstructuredPage pdfPage, PdfTextRectangle pdfTextRectangle, ITextMatch textParserMatch, PropertyInfo propertyInfo) { _Pdf = pdf; _PdfPage = pdfPage; _PdfTextRectangle = pdfTextRectangle; _TextMatch = textParserMatch; _PropertyInfo = propertyInfo; }
/// <summary> /// Devuelve true si la expresión regular sólo /// devuelve resultados válidos. /// </summary> /// <param name="textBound">TextBound</param> /// <param name="page">Página.</param> /// <param name="value">Valor.</param> /// <param name="converter">Converter.</param> /// <returns></returns> private static bool IsAllMatchesOK(ITextMatch textBound, PdfUnstructuredPage page, object value, dynamic converter) { // Debo evaluar tanto los aciertos como los errores, por ejemplo un // regex [\d\.\,]+(?=\s*€) devolverá aciertos en importes, pero también // muchos falsos positivos. Sólo queremos generar las regex que sean // significativas (es decir, que sólo devuelvan resultados buenos) MatchCollection matches = Regex.Matches(page.PdfText, textBound.Pattern); foreach (Match match in Regex.Matches(page.PdfText, textBound.Pattern)) { if (!converter.Convert(match.Value).Equals(value)) { return(false); } } return(true); }
public TextMatchTests() { _textMatch = new TextMatch(); }
/// <summary> /// Devuelve las coincidencias entre los datos /// del pdf, y los metadatos facilitados. /// <code lang="C#"> /// // Partiendo de una entrada de datos no estructurados de pdf /// PdfUnstructuredDoc pdf = new PdfUnstructuredDoc(@"C:\ProgramData\PdfTagger\Inbox\0000021101.pdf"); /// /// // y de un conjunto de datos estructurados /// InvoiceMetadata metadata = new InvoiceMetadata(); /// /// metadata.InvoiceNumber = "1 / 33050"; /// metadata.BuyerPartyID = "ES - A12070330"; /// metadata.IssueDate = new DateTime(2017, 11, 30); /// metadata.GrossAmount = 3646.50m; /// metadata.TaxesOutputsBase01 = 3013.64m; /// metadata.TaxesOutputsRate01 = 21m; /// metadata.TaxesOutputsAmount01 = 632.86m; /// /// PdfCompareResult compareResult = PdfCompare.Compare(new BusinessHierarchySet(), pdf, metadata); /// </code> /// <code lang="VB"> /// ' Partiendo de una entrada de datos no estructurados de pdf /// Dim pdf As PdfUnstructuredDoc = New PdfUnstructuredDoc(@"C:\ProgramData\PdfTagger\Inbox\0000021101.pdf") /// /// ' y de un conjunto de datos estructurados /// Dim metadata As InvoiceMetadata = New InvoiceMetadata() /// /// metadata.InvoiceNumber = "1 / 33050" /// metadata.BuyerPartyID = "ES - A12070330" /// metadata.IssueDate = New Date(2017, 11, 30) /// metadata.GrossAmount = CDec(3646.5) /// metadata.TaxesOutputsBase01 = CDec(3013.64) /// metadata.TaxesOutputsRate01 = 21 /// metadata.TaxesOutputsAmount01 = CDec(632.86) /// /// Dim compareResult As PdfCompareResult = PdfCompare.Compare(New BusinessHierarchySet(), pdf, metadata) /// </code> /// </summary> /// <param name="hierarchySet">Catalogo de jerarquías de analizadores /// por tipo. La operación utilizara para comparar cada tipo de variable /// el parser obtenido del catálogo. La comparación se irá ejecutando /// por cada uno de los parsers según su orden en la jerarquía, hasta /// que se encuentre un valor coincidente o se llegue al final /// de la jerarquía.</param> /// <param name="pdf">Instancia de la clase PdfUnstructuredDoc fruto /// del análisis y obtención de los datos no estructurados de un pdf.</param> /// <param name="metadata">Datos estructurados a comparar con los /// datos no estructurados obtenidos del pdf.</param> /// <returns>Instancia de la clase PdfCompareResult con /// los resultados obtenidos de la comparación.</returns> public static PdfCompareResult Compare(IHierarchySet hierarchySet, PdfUnstructuredDoc pdf, IMetadata metadata) { PdfCompareResult compareResult = new PdfCompareResult(pdf, metadata, hierarchySet); foreach (PropertyInfo pInf in metadata.GetType().GetProperties()) { object pValue = pInf.GetValue(metadata); // Obtengo la jerarquía de analizadores ITextParserHierarchy parserHierarchy = hierarchySet.GetParserHierarchy(pInf); if (pInf.PropertyType == typeof(string)) { parserHierarchy.SetParserRegexPattern(0, TxtRegex.Replace($"{pValue}")); } // Recorro todos los datos del pdf que quiero comparar if (parserHierarchy != null && pValue != null && !IsZeroNumeric(pValue)) { foreach (var page in pdf.PdfUnstructuredPages) { // Grupos de palabras foreach (var wordGroup in page.WordGroups) { foreach (var match in parserHierarchy.GetMatches(pValue, wordGroup.Text)) { compareResult.WordGroupsInfos.Add(new PdfCompareInfo(pdf, page, wordGroup, match, pInf, null)); } } // Grupos de líneas foreach (var line in page.Lines) { foreach (var match in parserHierarchy.GetMatches(pValue, line.Text)) { compareResult.LinesInfos.Add(new PdfCompareInfo(pdf, page, line, match, pInf, null)); } } // Grupos de texto con porpiedades como el color de la fuente foreach (var textString in page.TextStringGroups) { foreach (var match in parserHierarchy.GetMatches(pValue, textString.Text)) { PdfClownTextString tsNA = new PdfClownTextString(textString.Text, textString.ColorFill, textString.ColorStroke, textString.FontType, textString.FontSize) { Rectangle = textString.Rectangle, Type = "NA" }; PdfClownTextString tsX = new PdfClownTextString(textString.Text, textString.ColorFill, textString.ColorStroke, textString.FontType, textString.FontSize) { Type = "X", Rectangle = textString.Rectangle }; PdfClownTextString tsY = new PdfClownTextString(textString.Text, textString.ColorFill, textString.ColorStroke, textString.FontType, textString.FontSize) { Type = "Y", Rectangle = textString.Rectangle }; compareResult.TextStringInfos.Add(new PdfCompareInfo(pdf, page, null, match, pInf, tsNA)); compareResult.TextStringInfos.Add(new PdfCompareInfo(pdf, page, null, match, pInf, tsX)); compareResult.TextStringInfos.Add(new PdfCompareInfo(pdf, page, null, match, pInf, tsY)); } } foreach (var match in parserHierarchy.GetMatches(pValue, page.PdfText)) { Type txtBoundMatchGenType = typeof(TextBoundMatch <>).MakeGenericType(pInf.PropertyType); ITextMatch txtBoundMatch = (ITextMatch)Activator.CreateInstance(txtBoundMatchGenType, match); ITextMatch txtBoundMatchSoft = (ITextMatch)Activator.CreateInstance(txtBoundMatchGenType, match); (txtBoundMatchSoft as ITextBoundMatch).UseLengthOnPatternDigitReplacement = false; if (txtBoundMatch.Pattern != null) { dynamic converter = parserHierarchy.GetConverter(match.Pattern); // Límites contextuales if (IsAllMatchesOK(txtBoundMatch, page, pValue, converter)) { compareResult.PdfTextInfos.Add( new PdfCompareInfo(pdf, page, null, txtBoundMatch, pInf, null)); } // Límites contextuales menos estrictos if (IsAllMatchesOK(txtBoundMatchSoft, page, pValue, converter)) { compareResult.PdfTextInfos.Add( new PdfCompareInfo(pdf, page, null, txtBoundMatchSoft, pInf, null)); } } } } } } return(compareResult); }
public TextMatchController(ITextMatch textMatch) { _textMatch = textMatch; }