0

I have a string with 2 possibilities:

var desc = "Keyword1: That text I want \r\n Keyword2: Value2 \r\n Keyword3: Value3 \r\n Keyword4: Value4"

var desc = "Keyword1: That text I want Keyword2: Value2 \r\n Keyword3: Value3 \r\n Keyword4: Value4"

where the order of the keywords after the text "That text I want" Keyword2, Keyword3, Keyword4 doesn't matter and they are all optional.

I tried with the Regex Keyword1:(\s+)(.*)(\W+?)(\r\n?)(?=Keyword2:|Keyword3:|Keyword4:)

It does not work. Not sure what is wrong in my regex.

Any help is highly appreciated.

Thanks in advance!

Prince Vegeta
  • 719
  • 6
  • 21
  • Hello and welcome, if you [format your question](https://meta.stackexchange.com/questions/22186/how-do-i-format-my-code-blocks), it would be much easier to read. Maybe it helps if you try to solve your problem with [online regex](https://regex101.com/)? – Mar Tin Jul 16 '19 at 09:53
  • One possible cause is that you might be specifying that regex as a C# string just between double quotes. Therefore, those `\r\n` end up being actual carriage return and new line, instead of those characters for the regex. You would need to either use ``\\`` for any ``\`` in your regex so the string has actual backslashes (e.g.: `\\r\\n`), or add a `@` before the initial `"`. – Andrew Jul 16 '19 at 10:03
  • So, the text you want is always delimited by `Keyword1: ` and then either by `\r\n` or `Keyword2 :`? – Andrew Jul 16 '19 at 10:55
  • @Andrew, Yes the text I want is always delimited by keyword1: and then either by \r\n or (Keyword2: or Keyword3: or Keyword4) The Keyword2, Keyword3, Keyword4 could also be in any order. (3*2 possibilities) – sonu davidson.. Jul 16 '19 at 11:21
  • @sonudavidson.., so did my answer work? It would be great if you provide some feedback. – Andrew Jul 17 '19 at 03:05
  • @Andrew, Your answer gave me an idea to solve the regex issue. Thank you! – sonu davidson.. Jul 18 '19 at 13:43
  • Can you please add how it was solved then? It may be useful for someone else in the future. If my answer was close enough, you can mark it as accepted with the tick mark. Otherwise, you can add your own answer and accept it, so your question does not remain open. – Andrew Jul 18 '19 at 17:14

3 Answers3

0

Show here for the solution.

In your case you could simply use (regex between two strings):

(?<=Keyword1:)(.*)(?=Keyword2)

Try it out

Hope it helps.

Mar Tin
  • 2,132
  • 1
  • 26
  • 46
  • Beware that if `Keyword2` appears more than once (maybe as value of another keyword), the middle group will capture more than expected. Furthermore, in the first case it's also capturing the `\r\n`. – Andrew Jul 16 '19 at 10:50
0

Assuming those \r\n are actual special characters in the string and not the literals, this should work:

Keyword1: (.*?)(Keyword2:|Keyword3:|Keyword4:|\r\n)

You need to get the second grouping from the match. For example: match.Groups[1].

This regex matches Keyword1:, followed by the minimum amount of necessary characters, and then followed by either Keyword2: or \r\n (special characters). If those are literals in your input string, you will need to double those backslashes.

You can check it here. Note that on the right, Group 1 contains your text in both cases.

Andrew
  • 7,602
  • 2
  • 34
  • 42
0
       var pattern = keywordName + @":\s+(.+?)\r?\n";
        var regex = new Regex(pattern);
        var match = regex.Match(description);

        if (!match.Success) return null;

        var firstMatch = match.Groups[1].Value;

        //Find if there's another keyword in the extracted Value
        var lstKeywords = Enum.GetValues(typeof(Keywords)).Cast<Keywords>().Where(k => k != keywordName);

        //Add : to the last value so that it's recognized as a keyword
        var sOtherKeywords = string.Join(":|", lstKeywords) + ":";

        var pattern2 = @"(" + sOtherKeywords + @")(\s+)";
        regex = new Regex(pattern2);
        match = regex.Match(firstMatch);

        //If there's no other keyword in the same line then return the expression that is extracted from the first regex
        if (!match.Success) return firstMatch;

        var secondMatch = match.Groups[1].Value;

        var pattern3 = keywordName + @":\s+(.+)(\r?\n?)" + secondMatch;
        regex = new Regex(pattern3);
        match = regex.Match(description);

        return match.Success ? match.Groups[1].Value.TrimEnd() : null;