Home > database >  C# Regex matching two numbers divided by specific string and surrounded by brackets
C# Regex matching two numbers divided by specific string and surrounded by brackets

Time:01-14

I'm looking for a .NET Regex pattern that matches the following:

  • string starts with the [ character
  • followed by an integer or decimal number
  • followed by .. (space character, dot, dot, space character)
  • followed by an integer or decimal number
  • followed by the last character of the string which is )

*- the decimal numbers have a decimal separator, the . character

*- the integer numbers or the integer value of the decimal numbers should have a maximum of 4 digits

*- the decimal numbers should have a maximum of 4 fractional digits

*- the numbers can be negative

*- if a number is positive then the sign is missing

*- doesn't matter which one of the two numbers is smaller (first number can be bigger than the second one, "[56 .. 55)" for instance)

The pattern should match the following:

"[10 .. 15)"
"[100 .. 15.2)"
"[10.431 .. 15)"
"[-10.3 .. -5)"
"[-10.4 .. 5.12)"
"[10.4312 .. -5.1232)"

I'd also like to obtain the 2 numbers as strings from the string in case the pattern matches:

obtain "10" and "15" from "[10 .. 15)"

obtain "-10.4" and "5.12" from "[-10.4 .. 5.12)"

I've got so far to match an integer number including the .. string after, but got stuck in matching the second number. Adding "\d " to the pattern as I did in pattern2 seems to not work.

// ^\[          check string starts with [
// [\-]?        check it's followed by zero or one "-" character
// \d           look for one or more digits
// (?=\ \.\.\ ) check it's followed by the " .. " string

var testString1 = "[-10 .. ";
var pattern1 = @"^\[[\-]?\d (?=\ \.\.\ )";

Regex.IsMatch(testString1, pattern1); // returns true

var testString2 = "[-10 .. 1";
var pattern2 = @"^\[[\-]?\d (?=\ \.\.\ )\d ";

Regex.IsMatch(testString2 , pattern2); // returns false

CodePudding user response:

You can use

^\[(-?\d (?:\.\d )?) \.\. (-?\d (?:\.\d )?)\)$
^\[(-?\d*\.?\d ) \.\. (-?\d*\.?\d )\)$

See the regex demo / regex demo #2. Details:

  • ^ - start of string
  • \[ - a [ char
  • (-?\d (?:\.\d )?) - Group 1: an optional -, one or more digits and then an optional sequence of a . and one or more digits
  • \.\. - a .. string
  • (-?\d (?:\.\d )?) - Group 2: an optional -, one or more digits and then an optional sequence of a . and one or more digits
  • \) - a ) char
  • $ - end of string (use \z if you need to check for the very end of string).

See the C# demo:

var texts = new List<string> { "[10 .. 15)", "[100 .. 15.2)", "[10.431 .. 15)", "[-10.3 .. -5)", "[-10.4 .. 5.12)", "[10.4312 .. -5.1232)" };
var pattern = new Regex(@"^\[(-?\d (?:\.\d )?) \.\. (-?\d (?:\.\d )?)\)$");
foreach (var s in texts) 
{
    Console.WriteLine($"---- {s} ----");
    var match = pattern.Match(s);
    if (match.Success) 
    {
        Console.WriteLine($"Group 1: {match.Groups[1].Value}, Group 2: {match.Groups[2].Value}");
    }
    else
    {
        Console.WriteLine($"No match found in '{s}'.");
    }
}

Output:

---- [10 .. 15) ----
Group 1: 10, Group 2: 15
---- [100 .. 15.2) ----
Group 1: 100, Group 2: 15.2
---- [10.431 .. 15) ----
Group 1: 10.431, Group 2: 15
---- [-10.3 .. -5) ----
Group 1: -10.3, Group 2: -5
---- [-10.4 .. 5.12) ----
Group 1: -10.4, Group 2: 5.12
---- [10.4312 .. -5.1232) ----
Group 1: 10.4312, Group 2: -5.1232

CodePudding user response:

This works (see this .Net Fiddle:

using System;
using System.Text.RegularExpressions;
                    
public class Program
{
    public static void Main()
    {
        Match m = rx.Match("[123 .. -9876.5432]");
        if (!m.Success )
        {
            Console.WriteLine("No Match");
        }
        else
        {
          Console.WriteLine(@"left:  {0}", m.Groups[ "left"  ] );
          Console.WriteLine(@"right: {0}", m.Groups[ "right" ] );
        }
    }
    
    private static readonly Regex rx = new Regex(@"
        ^                      # anchor match at start-of-text
        [[]                    # a left square bracket followed by
          (?<left>             # a named capturing group, containing a number, consisting of
            -?[0-9]{1,4}       # - a mandatory integer portion followed by
            ([.][0-9]{1,4})?   # - an optional fractional portion
          )                    # the whole of which is followed by
        [ ][.][.][ ]           # a separator (' .. '), followed by
          (?<right>            # another named capturing group containing a number, consisting of
            -?[0-9]{1,4}       # - a mandatory integer portion followed by
            ([.][0-9]{1,4})?   # - an optional fractional portion
          )                    # the whole of which is followed by
        \]                     # a right square bracket, followed by
        $                      # end-of-text
      ",
      RegexOptions.IgnorePatternWhitespace|RegexOptions.ExplicitCapture
    );
    
}

CodePudding user response:

The following regex should be fine.

^\[-?\d (?:\.\d )? \.\. -?\d (?:\.\d )?\)$
var pattern = @"^\[-?\d (?:\.\d )? \.\. -?\d (?:\.\d )?\)$";
var inputs = new[]{"[10 .. 15)", "[100 .. 15.2)", "[10.431 .. 15)", "[-10.3 .. -5)", "[-10.4 .. 5.12)", "[10.4312 .. -5.1232)", };
foreach (var input in inputs)
{
    Console.WriteLine(input   " = "   Regex.IsMatch(input, pattern));
}

// [10 .. 15) = True
// [100 .. 15.2) = True
// [10.431 .. 15) = True
// [-10.3 .. -5) = True
// [-10.4 .. 5.12) = True
// [10.4312 .. -5.1232) = True

https://dotnetfiddle.net/LpswtI

  •  Tags:  
  • Related