PythagorasDoe
PythagorasDoe

Reputation: 55

Find Regex Expression only after finding a given String

I am trying to create a method that receives a text and a string and use regex to find a datetime, associated with the given string.

I don't know the position of the regex match. It can be everywhere and change overtime since the text is editable. The following example have 3 options, but can have 10, 25 or even 100.

At the moment, i already created the method that founds the datetime however it is the first match and not the one after the given string.

private static DateTime getLastExecutionTime(string text, string nameFile)
{
    string lastRun = string.Empty;

    if (Regex.IsMatch(text, nameFile))
    {
        lastRun = Regex.Match(text, "[0-9]{2}-[0-9]{2}-[0-9]{4} [0-9]{2}:[0-9]{2}").ToString();

        return DateTime.Parse(lastRun);
    }

    return nullDate;
}

    =============
    INPUT EXAMPLE
    =============
    text = "Cat 01-08-2019 16:32\r\nDog 03-08-2019 12:32\r\nBear 13-07-2019 19:22"
    nameFile = "Dog"

    ===============
    EXPECTED OUTPUT
    ===============
    lastRun = "03-08-2019 12:32"

Upvotes: 2

Views: 77

Answers (4)

EylM
EylM

Reputation: 6103

If your date recogniser is the name of the file, you need to add it to the regular expression. In this example, this Regex.Match will find a date followed by "Dog".

var matches = Regex.Match(text, "Dog ([0-9]{2}-[0-9]{2}-[0-9]{4} [0-9]{2}:[0-9])");

Or in a more generic way:

    var matches = Regex.Match(text, nameFile + " ([0-9]{2}-[0-9]{2}-[0-9]{4} [0-9]{2}:[0-9])");

In this case, you you need to access the "Group1" of the match result. The group at index 0 will return the match without the groups.

matches[0].Groups[1].Value

More about MatchCollection: MSDN

Upvotes: 0

Tim Biegeleisen
Tim Biegeleisen

Reputation: 521093

We can try doing a one-liner regex replacement using the following pattern:

^[\s\S]*([0-9]{2}-[0-9]{2}-[0-9]{4} [0-9]{2}:[0-9]{2})[\s\S]*$

Script:

string text = "Cat 01-08-2019 16:32\r\nDog 03-08-2019 12:32";
string pattern = @"^[\s\S]*([0-9]{2}-[0-9]{2}-[0-9]{4} [0-9]{2}:[0-9]{2})[\s\S]*$";
string output = Regex.Replace(text, pattern, "$1");
Console.WriteLine(output);

This prints:

03-08-2019 12:32

Upvotes: 0

Guilhem Prev
Guilhem Prev

Reputation: 979

An option will be to remove all the text before your nameFile by using Substring and IndexOf.

private static DateTime getLastExecutionTime(string text, string nameFile)
{
    string lastRun = string.Empty;

    if (Regex.IsMatch(text, nameFile))
    {
        lastRun = Regex.Match(text.Substring(text.IndexOf(nameFile)), " [0-9]{2}-[0-9]{2}-[0-9]{4} [0-9]{2}:[0-9]{2}").ToString();

        return DateTime.Parse(lastRun);
    }

    return new DateTime();
}

You can also used a full regex solution :

private static DateTime getLastExecutionTime(string text, string nameFile)
{
    string lastRun = Regex.Match(text, "(?:" + nameFile + ") ([0-9]{2}-[0-9]{2}-[0-9]{4} [0-9]{2}:[0-9]{2})").Groups[1].Value;

    if (string.IsNullOrEmpty(lastRun))
        return new DateTime();

    return DateTime.Parse(lastRun);
}

Upvotes: 1

astef
astef

Reputation: 9488

Try this expression:

Regex.Match(text, "^Dog (.+)$", RegexOptions.Multiline).Groups[1].Value

For your input in a text variable the output is: 03-08-2019 12:32

If you need to parametrize it, go ahead:

Regex.Match(text, $"^{query} (.+)$", RegexOptions.Multiline).Groups[1].Value

But make sure you're receiving the query from a trusted source, to prevent injection attacks.

You can quickly test expression here: https://regex101.com/

Upvotes: 0

Related Questions