bmt22033
bmt22033

Reputation: 7250

c# validate that string contains matching number of brackets

If I have a string like this...

"123[1-5]553[4-52]63244[19-44]"

...what's the best way to validate the following conditions:

  1. Every open bracket has a matching close bracket
  2. There are no more than 3 sets of brackets
  3. There are no nested brackets (i.e., [123-[4]9])

Would a regex be able to validate all of these scenarios? If not, how about LINQ?

Upvotes: 6

Views: 2793

Answers (3)

Guffa
Guffa

Reputation: 700562

Just to see if it would be plausible, here is a LINQ:y solution:

bool[] b =
  input.Where(c => c == '[' || c == ']')
  .Select((c,i) => (c == '[') == (i % 2 == 0))
  .ToArray();

bool valid = b.Length % 2 == 0 && b.Length <= 6 && b.All(i => i);

It filters out the [ and ] characters, then checks that there are only alternating brackets (starting with [), an even number, and not more than 6 of them.

Upvotes: 1

Eric J.
Eric J.

Reputation: 150138

The fastest way to do this would be just to iterate the string

bool Validate(string input) 
{
    int braceBalance = 0;
    int openCount = 0;
    for (int i = 0; i < input.Length; i++)
    {
        if (input[i] == '[') 
        {
            braceBalance++;
            openCount++;
        }
        if (openCount > 3) return false;  // More than 3 pairs
        if (input[i] == ']') braceBalance--;
        // Check for nesting:
        if (braceBalance < -1 || braceBalance > 1) return false;
    }
    return (braceBalance == 0); // Check for equal number of opening and closing
}

RegEx and Linq will both have greater overhead than this (although depending on your application, that may not matter).

Upvotes: 5

SLaks
SLaks

Reputation: 887777

Because you don't allow nesting, you can use a regex:

^([^[\]]*\[[^[\]]*\]){0,3}[^[\]]*$

Explanation:

  • (...){0,3} matches up to three sets of the following:
    • [^[\]]* matches optional non-bracket characters
    • \[ matches [ to open a group
    • [^[\]]* matches optional non-bracket characters inside the group
    • \] matches ] to close the group
  • Finally, [^[\]]* matches more optional non-bracket characters after all of the groups

Upvotes: 9

Related Questions