Как извлечь даты счета из текста

Текст, извлеченный из pdf, содержит даты после слова Дата или Дата: (может быть в нижнем регистре и может содержать или не содержать: в конце) и дату в формате 99.99.999 (начальные нули могут быть пропущены). Дата может быть также в следующей строке.

Дата после слов Date:, date, date: должна быть извлечена, она может быть и в следующей строке. Дата всегда указывается в формате d.m.yyyy, dd.mm.yyyy, d.mm.yyyy или dd.m.yyyy, разделенных точками.

Примеры:

Invoice date 03.04.2023

date 03.04.2023

Date: 3.4.2023

Inv. date
03.04.2023

Попытка найти совпадение с помощью

var text=@"    aaaa vvvv: 202305001
  XXXXX YYYYY xxx
  Inv. date:  1.05.2023
  Bula 14a
  Due:  10.05.2023
";

var dateexp = "^.*(?i)Date(.|\n)*\d\d\.\d\d\.\d\d\d\d.*\n";

    var rida = Regex.Match(tekst, dateexp, RegexOptions.Multiline);
    if (!rida.Success)
      throw new Exception();

не находит соответствия. Как найти эти даты?

Использование контроллера C# .NET 7 ASP.NET MVC.

Вы пробовали \d{1,2} вместо \d\d ​​?

Fildor 09.05.2023 11:05

Вы не зафиксировали дату. Заключите часть даты в круглые скобки. И никогда не используйте (.|\n)*, всегда используйте .* или .*? с опцией RegexOptions.Singleline. (?si)^.*Date.*?(\d\d\.\d\d\.\d{4}).*, а затем возьмите rida.Groups[1].Value, найдя совпадение.

Wiktor Stribiżew 09.05.2023 11:06

Из любопытства (и опыта): в PDF есть только один текстовый слой? Нет xml? Или это из OCR изображения в PDF?

Fildor 09.05.2023 11:10

в тексте у вас есть инв. дата и срок, какую дату вы хотите извлечь или обе? это всегда порядок дня, месяца и года или он меняется?

Maytham Fahmi 09.05.2023 11:17

Дата после слов Date:, date, date: должна быть извлечена, она может быть и в следующей строке. Дата всегда указывается в формате d.m.yyyy, dd.mm.yyyy, d.mm.yyyy или dd.m.yyyy, разделенных точками. я добавил это к вопросу

Andrus 09.05.2023 11:23

Когда вы знаете набор форматов, я бы не стал использовать Regex. DateTime.ParseExact имеет перегруженную версию, которая использует массив форматов для синтаксического анализа. learn.microsoft.com/en-us/dotnet/api/…

Ralf 09.05.2023 11:30

@Ralf Invoice может содержать разные даты в разных местах. Мне нужно знать, какая дата должна анализироваться. Перед правильной датой стоит слово, похожее на Date:.

Andrus 09.05.2023 11:36

Сделайте это просто: string pattern = @"date:\s+(?'date'.*)"; Match match = Regex.Match(text, pattern, RegexOptions.Multiline);

jdweng 09.05.2023 11:42

Значит, недостаточно найти такие ключевые слова, как «date:», «due:» и добавить следующее слово в DateTime.ParseExact? Для меня это означает, что если вы используете Regex больше, включая даты, которые не подходят, будут игнорироваться. Объединение Regex с DateTime.ParseExact приведет к ошибке при непредвиденных датах. Мне это кажется более безопасным.

Ralf 09.05.2023 11:42

Достаточно найти дату после слова даты. Однако может быть двоеточие после даты или дата может быть следующей строкой. после того, как дата найдена, применяется синтаксический анализ.

Andrus 09.05.2023 11:50

@WiktorStribiżew Спасибо, отличный комментарий. (?si)^.*Date.*?(\d{1,2}\.\d{1,2}\.\d{4}).* с опцией SingleLine работает.

Andrus 09.05.2023 12:00

Обратите внимание, что первый ^.* нужен только в том случае, если вы ожидаете несколько дат в строке, и вам нужно получить последнее совпадение. В противном случае просто удалите ^.* из шаблона. Последний .* можно убрать безоговорочно. Итак, (?si)Date.*?(\d{1,2}\.\d{1,2}\.\d{4}) может быть лучшим решением.

Wiktor Stribiżew 09.05.2023 12:02

Прекрасно работает. Я также добавил \b к вашему регулярному выражению: (?si)\bDate.*?(\d{1,2}\.\d{1,2}\.\d{4}) из ответа. Это безопаснее, он отбрасывает такие слова, как SomeDate?

Andrus 09.05.2023 14:32
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
13
57
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете изменить регулярное выражение, чтобы оно соответствовало формату даты и слову «Дата» в любом регистре (строчные или прописные), за которым следует двоеточие или нет. Вот обновленное регулярное выражение, которое должно соответствовать датам в упомянутых вами форматах:

(?i)\bDate\b:?[\r\n\s]*\d{1,2}\.\d{1,2}\.\d{4}

Объяснение регулярного выражения:

  • (?i) - Игнорировать флаг регистра
  • \bDate\b — Соответствует слову «Свидание», окруженному границами слов.
  • :? — соответствует необязательному двоеточию.
  • [\r\n\s]* — соответствует любой комбинации символов новой строки, возврата каретки или пробелов.
  • \d{1,2}\.\d{1,2}\.\d{4} – соответствует дате в формате д.м.гггг, дд.мм.гггг, д.мм.гггг или дд.м.гггг, разделенной точками.

Вот как вы можете использовать это регулярное выражение в C# для извлечения даты:

var text = @"    aaaa vvvv: 202305001
  XXXXX YYYYY xxx
  Inv. date:  1.05.2023
  Bula 14a
  Due:  10.05.2023
";

var regex = new Regex(@"(?i)\bDate\b:?[\r\n\s]*\d{1,2}\.\d{1,2}\.\d{4}");

var match = regex.Match(text);
if (match.Success)
{
    var date = DateTime.ParseExact(match.Value.Trim(), "d.M.yyyy", CultureInfo.InvariantCulture);
    Console.WriteLine(date.ToString("yyyy-MM-dd")); // Outputs: 2023-05-01
}
else
{
    Console.WriteLine("No match found.");
}

Этот код будет извлекать дату из текста и анализировать ее в объект DateTime с помощью метода ParseExact. Метод Trim используется для удаления любых начальных или конечных пробельных символов из совпавшей строки. Параметр CultureInfo.InvariantCulture используется для указания формата даты. Наконец, дата печатается в нужном формате с помощью метода ToString.

[\r\n\s] = \s.
Wiktor Stribiżew 09.05.2023 12:01

Другие вопросы по теме