1

I have these two strings:

 s = t 
 [ f ] s = t

and processing each with regex using this pattern:

(?<=]).*(?==|:)

My goal is trying to retrieve the " s " part (between the "]" and "="), though the "[ f ]" is optional, as you can see in the first line.

I've tried many different patterns found online and used by others, also spent the last 2 hours trying to figure this out with references, search engines, trial and error, but to no success.

How would I achieve this? What pattern would I need to achieve this?

Thanos Markou
  • 2,587
  • 3
  • 25
  • 32
Dean Reynolds
  • 377
  • 2
  • 12
  • 1
    What is the problem you are trying to solve here? A single example doesn't cut it. – nhahtdh Dec 01 '15 at 07:36
  • If your goal is to parse ini file, then https://stackoverflow.com/questions/217902/reading-writing-an-ini-file – nhahtdh Dec 01 '15 at 07:37

2 Answers2

1

Rather than using RegEx, why not use regular .NET methods? Always remember that regular expressions aren't silver bullets. An operation that takes a few lines of code can quickly become a convoluted mess in RegEx.

Your case can be solved by the following function:

static string GetKey(string line)
{
    string result = line.Split('=')[0];
    if (result.IndexOf('[') < result.IndexOf(']')) // preceded by an optional group
        result = result.Split(']')[1];

    return result;
}

Running your code through this function successfully retrieves the s on each line.

Alex Essilfie
  • 12,339
  • 9
  • 70
  • 108
  • Yours is an answer, a good one, though I purposely wanted to keep lines down to minimal for my own reasons, so I wanted to use regex for those reasons. – Dean Reynolds Dec 01 '15 at 18:51
1

You can use a regex for this task. Basically, the s must be some string of text between ] or start of line/string and a = symbol.

So, use

(?:^\p{Zs}*|])([^]=]*)=

See the regex demo

The regex breakdown:

  • (?:^\p{Zs}*|]) - a non-capturing group matching 2 alternatives:
    • ^\p{Zs}* - start of string/line (depends on RegexOptions used) followed by 0 or more horizontal whitespace symbols or...
    • ] - a literal ] symbol
  • ([^]=]*) - (Capture Group 1) 0 or more symbols that are not ] or =.
  • = - a literal = symbol

C# Code:

var strs = new List<string> { " [ f ] s = t", "s = t"};
var pattern = @"(?:^\p{Zs}*|])([^]=]*)=";
foreach (var s in strs)
{
    var match = Regex.Match(s, pattern);
    if (match.Success)
        Console.WriteLine(match.Groups[1].Value);
   }

If you need to get the value you need via Match.Value, you can use

@"(?<=^\p{Zs}*|])[^]=:]*(?=[=:])"

Here is the regex demo

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
  • Is there an extra bit to get rid of the ] and = at the start and end, I realize I could just substring at this point, just wondered. – Dean Reynolds Dec 01 '15 at 18:13
  • But you do not get them in the `Groups[1].Value`. If you need to get the `s` as a `match.Value`, you can use a much less efficient `var pattern = @"(?<=^\p{Zs}*|])[^]=]*(?==)";`. – Wiktor Stribiżew Dec 01 '15 at 18:17
  • I'm using .value, but it also gets the ] and =, I don't mind substringing, how about if the = sign was a colon or an equals? – Dean Reynolds Dec 01 '15 at 18:22
  • The value you need can be obtained by accessing `match.Groups[1].Value` with my original answer, it is possible due to the capturing group (round brackets) in the pattern that *captures* a part of the matched substring into a separate buffer. It is best practice to use capturing groups where lookarounds turn out inefficient. But the regex in my previous comment should work for you well even with `match.Value`. – Wiktor Stribiżew Dec 01 '15 at 18:27
  • It worked! [regex tester](http://regexstorm.net/tester?p=(%3f%3c%3d%5e%5cp%7bZs%7d*%7c%5d)%5b%5e%5d%3d%3a%5d*(%3f%3d%3d%7c%3a)&i=+%5b+f+%5d+s+%3d+t%0d%0as+%3d+t+%0d%0a+%5b+f+%5d+s+%3d+t%0d%0as+%3d+t+%0d%0as+%3d+t+%0d%0as%3at%0d%0as+%3a+t%0d%0a+s+%3a+t+%0d%0a+%5b+f+%5d+s+%3a+t+&o=m) – Dean Reynolds Dec 01 '15 at 18:49