C # Извлечение нескольких строк в разных форматах из строки - PullRequest
0 голосов
/ 21 февраля 2019

Я не уверен, что это лучшее место, чтобы спросить это или нет, поэтому заранее извиняюсь, если нет.

У меня есть необходимость извлечь несколько строк из строки.Однако формат дат может варьироваться от строки к строке (формат двух дат в одной строке должен быть одинаковым), а текст вокруг дат также может различаться.У меня нет контроля над строками, но все они будут в британском порядке дня и месяца.Примеры строк включают, но не ограничиваются:

с 1 марта 1960 г. по 1 марта 2235

за период, начинающийся с 1/3/1960 и заканчивающийся 1/3/2235

Начиная с 1.3.1960 и заканчивая 1.3.2235

В настоящее время я думаю о том, чтобы запустить несколько RegEx для строки, по одному для каждого потенциального формата, с некоторой логикой, чтобы ограничить какие из нихиспользовать (например, если строка содержит '/', я бы запустил те варианты RegEx, которые используют это в первую очередь).

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

Ответы [ 2 ]

0 голосов
/ 21 февраля 2019

Вы можете использовать два регулярных выражения и одну замену, а затем использовать DateTime.ParseExact для преобразования дат в объекте DateTime.Возможно, что-то вроде этого:

string[] lines = { "From 1 March 1960 To 1 March 2235", 
                   "For a period starting 1/3/1960 and ending 1/3/2235", 
                   "Starting 1.3.1960 and ending 1.3.2235", 
                   "Just some string with no dates in it" };
foreach (string line in lines) {

    Console.ForegroundColor = ConsoleColor.Yellow;
    Console.WriteLine(System.Environment.NewLine + line);
    Console.ResetColor();

    if (Regex.IsMatch(line, @"(\d{1,2}\s+\w+\s+\d{4})"))
    {
        Regex regexObj = new Regex(@"(\d{1,2}\s+\w+\s+\d{4})");
        Match matchResults = regexObj.Match(line);
        while (matchResults.Success)
        {
            DateTime dte = DateTime.ParseExact(matchResults.Value, "d MMMM yyyy", CultureInfo.GetCultureInfo("en-GB"));
            Console.WriteLine(dte.ToShortDateString());
            matchResults = matchResults.NextMatch();
        }
    }
    else if (Regex.IsMatch(line, @"(\d{1,2}[./]\d{1,2}[./]\d{4})"))
    {
        Regex regexObj = new Regex(@"(\d{1,2}[./]\d{1,2}[./]\d{4})");
        Match matchResults = regexObj.Match(line);
        while (matchResults.Success)
        {
            DateTime dte = DateTime.ParseExact(matchResults.Value.Replace(".","/"), "d/M/yyyy", CultureInfo.GetCultureInfo("en-GB"));
            Console.WriteLine(dte.ToShortDateString());
            matchResults = matchResults.NextMatch();
        }
    }
    else { Console.WriteLine("No valid date found."); }

}

Вышеуказанное возвращает

From 1 March 1960 To 1 March 2235
1/3/1960
1/3/2235

For a period starting 1/3/1960 and ending 1/3/2235
1/3/1960
1/3/2235

Starting 1.3.1960 and ending 1.3.2235
1/3/1960
1/3/2235

Just some string with no dates in it
No valid date found.
0 голосов
/ 21 февраля 2019

Попробуйте Regex: \b(?:(?:31(\/|-| |\.)(?:0?[13578]|1[02]|(?:Jan|January|Mar|March|May|Jul|July|Aug|August|Oct|October|Dec|December)))\1|(?:(?:29|30)(\/|-| |\.)(?:0?[1,3-9]|1[0-2]|(?:Jan|January|Mar|March|Apr|April|May|Jun|June|Jul|July|Aug|August|Sep|September|Oct|October|Nov|November|Dec|December))\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})\b|\b(?:29(\/|-| |\.)(?:0?2|(?:Feb|February))\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))\b|\b(?:0?[1-9]|1\d|2[0-8])(\/|-| |\.)(?:(?:0?[1-9]|(?:Jan|January|Feb|February|Mar|March|Apr|April|May|Jun|June|Jul|July|Aug|August|Sep|September))|(?:1[0-2]|(?:Oct|October|Nov|November|Dec|December)))\4(?:(?:1[6-9]|[2-9]\d)?\d{2})\b

Демо

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