Текст, извлеченный из 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.
Вы не зафиксировали дату. Заключите часть даты в круглые скобки. И никогда не используйте (.|\n)*, всегда используйте .* или .*? с опцией RegexOptions.Singleline. (?si)^.*Date.*?(\d\d\.\d\d\.\d{4}).*, а затем возьмите rida.Groups[1].Value, найдя совпадение.
Из любопытства (и опыта): в PDF есть только один текстовый слой? Нет xml? Или это из OCR изображения в PDF?
в тексте у вас есть инв. дата и срок, какую дату вы хотите извлечь или обе? это всегда порядок дня, месяца и года или он меняется?
Дата после слов Date:, date, date: должна быть извлечена, она может быть и в следующей строке. Дата всегда указывается в формате d.m.yyyy, dd.mm.yyyy, d.mm.yyyy или dd.m.yyyy, разделенных точками. я добавил это к вопросу
Когда вы знаете набор форматов, я бы не стал использовать Regex. DateTime.ParseExact имеет перегруженную версию, которая использует массив форматов для синтаксического анализа. learn.microsoft.com/en-us/dotnet/api/…
@Ralf Invoice может содержать разные даты в разных местах. Мне нужно знать, какая дата должна анализироваться. Перед правильной датой стоит слово, похожее на Date:.
Сделайте это просто: string pattern = @"date:\s+(?'date'.*)"; Match match = Regex.Match(text, pattern, RegexOptions.Multiline);
Значит, недостаточно найти такие ключевые слова, как «date:», «due:» и добавить следующее слово в DateTime.ParseExact? Для меня это означает, что если вы используете Regex больше, включая даты, которые не подходят, будут игнорироваться. Объединение Regex с DateTime.ParseExact приведет к ошибке при непредвиденных датах. Мне это кажется более безопасным.
Достаточно найти дату после слова даты. Однако может быть двоеточие после даты или дата может быть следующей строкой. после того, как дата найдена, применяется синтаксический анализ.
@WiktorStribiżew Спасибо, отличный комментарий. (?si)^.*Date.*?(\d{1,2}\.\d{1,2}\.\d{4}).* с опцией SingleLine работает.
Обратите внимание, что первый ^.* нужен только в том случае, если вы ожидаете несколько дат в строке, и вам нужно получить последнее совпадение. В противном случае просто удалите ^.* из шаблона. Последний .* можно убрать безоговорочно. Итак, (?si)Date.*?(\d{1,2}\.\d{1,2}\.\d{4}) может быть лучшим решением.
Прекрасно работает. Я также добавил \b к вашему регулярному выражению: (?si)\bDate.*?(\d{1,2}\.\d{1,2}\.\d{4}) из ответа. Это безопаснее, он отбрасывает такие слова, как SomeDate?





Вы можете изменить регулярное выражение, чтобы оно соответствовало формату даты и слову «Дата» в любом регистре (строчные или прописные), за которым следует двоеточие или нет. Вот обновленное регулярное выражение, которое должно соответствовать датам в упомянутых вами форматах:
(?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.
Вы пробовали \d{1,2} вместо \d\d ?