Итак, я использовал iText7 на C# для извлечения и выделения данных PDF. Раньше я использовал iTextSharp 5, и он хорошо справлялся с тем, что мне было нужно, я перенес некоторые функции, но решил начать использовать RegexBasedLocationExtractionStrategy для поиска прямоугольников, которые мне нужно выделить, а не модифицированную версию TextLocationExtractionStrategy . Проблема, с которой я сталкиваюсь, заключается в том, что у меня есть PDF-файл (к сожалению, не могу поделиться, но я пытаюсь создать тот, который может воспроизвести проблему), который содержит словосочетание «Кровяное давление», и у меня есть следующий оператор регулярного выражения @"\b\.blood\spressure\b"
. Я проверил, что этот оператор регулярного выражения находит совпадение текста в PDF-документе, когда я извлекаю весь текст страницы, но когда я запускаю его с помощью стратегии Regex, он не возвращает результат совпадения для той же самой страницы. Ниже приведен код, который я использую
foreach (string searchTerm in Model.SearchTerms)
{
if (searchTerm.Contains(" "))
{
var split = searchTerm.Split(" ");
foreach (string item in split)
{
term += item + @"\s";
}
char[] trim = new char[2] { 's', '\\' };
term = term.Trim(trim);
}
else
{
term = searchTerm;
}
regexList.Add(@"\b" + term + @"\b");
regexList.Add(@"\b\." + term + @"\b");
regexList.Add(@"\.\b" + term + @"\b");
regexList.Add(@"\b" + term + @"s\b");
regexList.Add(@"\b" + term + @"\.\b");
regexList.Add(@"\b" + term + @"\s\b");
}
searchRegex = new Regex(string.Join('|', regexList), RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.IgnorePatternWhitespace);
for (int i = Model.BlankPages + 1; i <= pdfDocument.GetNumberOfPages(); i++)
{
extractionStrategy = new RegexBasedLocationExtractionStrategy(searchRegex);
canvasProcessor = new PdfCanvasProcessor(extractionStrategy);
canvasProcessor.ProcessPageContent(pdfDocument.GetPage(i));
page = pdfDocument.GetPage(i);
pageRectangles.Add(new KeyValuePair<PdfPage, List<Rectangle>>(page, extractionStrategy.GetResultantLocations().Select(x => x.GetRectangle()).ToList()));
}
Я проверил, что текст есть, и мое регулярное выражение работает со следующим
for (int page = 1; page <= numberOfPages; page++)
{
strategy = new LocationTextExtractionStrategy();
pageText = PdfTextExtractor.GetTextFromPage(pdfDocument.GetPage(page), strategy);
pageValuePairs.Add(page, pageText);
}
// code break to seperate helper method where searchString is the pageText from the above code
public static KeyValuePair<Regex, bool> FindString(string searchTerm, string searchString)
{
List<string> regexList = new List<string>();
string term = "";
if (searchTerm.Contains(" "))
{
var split = searchTerm.Split(" ");
foreach (string item in split)
{
term += item + @"\s";
}
char[] trim = new char[2] { 's', '\\' };
term = term.Trim(trim);
}
else
{
term = searchTerm;
}
regexList.Add(@"\b" + term + @"\b");
regexList.Add(@"\b\." + term + @"\b");
regexList.Add(@"\.\b" + term + @"\b");
regexList.Add(@"\b" + term + @"s\b");
regexList.Add(@"\b" + term + @"\.\b");
regexList.Add(@"\b" + term + @"\s\b");
Regex searchRegex = new Regex(string.Join('|', regexList), RegexOptions.IgnoreCase);
if (searchRegex.IsMatch(searchString))
{
return new KeyValuePair<Regex, bool>(searchRegex, true);
}
return new KeyValuePair<Regex, bool>(null, false);
}
Это фрагмент текста, который содержит указанный термин "\nPulse 1: 100 bpm \nBlood Pressure 1:"
после осмотра я не нашел причин для несоответствия, нет нечетных символов пробела, я пробовал с RegexOptions.SingleLine и без него, но изменений не было. Я действительно не понимаю, в какой строке он ищет, если она отличается от той, которую я ищу (и почему), и как я могу исправить эту проблему.
Примечание: я знаю, что это не так. Выглядит не очень хорошо, это все еще PO C, но этот код, в частности, действительно находит прямоугольники примерно для 150 поисковых запросов и работает безумно быстро по сравнению с моей предыдущей версией iTextSharp 5, 200-страничного документа со 150 поисковыми запросами и 5000 совпадений в старой версии занимали ~ 45-60 секунд, вышеупомянутая версия с более высокой точностью (за исключением этого одного случая "кровяного давления") занимает менее 5 секунд и в среднем по всем документам менее секунды.
РЕДАКТИРОВАТЬ Я , возможно, пришел к выводу, что это проблема в RegexBasedLocationExtractionStrategy в том смысле, что он ищет по одному слову за раз, а не целую строку сразу, что делает невозможным найти фразу через ее logi c. Я верю в это, поскольку обнаружил, что другие результаты при поиске по регулярным выражениям из нескольких слов совпадают в других документах. Если у кого-то есть дополнительные знания по этому поводу, обновите и сообщите по мере необходимости
Чтобы дискредитировать себя, я создал PDF-файл, содержащий кучу разного контента, включая шаблоны из нескольких слов, и метод нашел его, но основной текст идентичен тексту, который у меня есть в документе, где он его не нашел. Я не уверен, что могло бы вызвать это, это очень озадачивает.