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\zif 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
