Reputation: 78
I want to validate a string based on custom format: (_.__,_.__)
. This should be a decimal input followed by a comma followed by another decimal input, wrapped in a parentheses—e.g.(1.01,3.21)
. I want the string pattern to accept one and more entries—e.g.(1.01,3.21)(3.01,4.51)...(2.1,5.6)
. Is it possible to do that?
Upvotes: 5
Views: 211
Reputation:
One way to solve this is:
(x,y)
pattern.x
and y
.x
and y
are of decimal
type using decimal.TryParse(..)
method.private bool IsValidInput(string input)
{
var pattern = @"\((.*?)\s?,\s?(.*?)\)";
var xpatt = @"\s+\(|\s+\)|\,\(|\)\,|\)\s+|\({2,}|\){2,}|^\)\(|\)\($";
var q = Regex.Matches(input, pattern)
.Cast<Match>()
.SelectMany(x => x.Groups.Cast<Group>()
.Skip(1))
.Select(x => x.Value);
return !Regex.IsMatch(input, xpatt)
&& q.Count() > 0
&& input.Replace(" ","").Length
== (input.Count(x => x == '(' || x == ')' || x == ',')
+ q.Sum(x => x.Length))
&& q.All(x => decimal.TryParse(x, out _));
}
So, the function returns:
(1.01, 3.21)(3.01, 4.51)(2.1, 5.6) => true
(abc, 3.21)(3.01, 4.51)(2.1, 5.6) => false
(3.21)(3.01, 4.51)(2.1, 5.6) => false
1.01, 3.2 13.01, 4.51 2.1, 5.6 => false
1.01, 3.21)(3.01, 4.51)(2.1, 5.6) => false
(1.01, 3.21)(3.01, 4.51)(2.1, 5.6 => false
1.01, 3.21)3.01, 4.51)2.1, 5.6) => false
(1.01, 3.21)3.01, 4.51(2.1, 5.6) => false
(1.01, 3.21)abc(3.01, 4.51)(2.1, 5.6) => false
(1.01, 3.21)(3.01, 4.51)abc(2.1, 5.6) => false
abc(1.01, 3.21)(3.01, 4.51)(2.1, 5.6) => false
(1.01, 3.21)(3.01, 4.51)(2.1, 5.6)abc => false
Upvotes: 3
Reputation: 2850
You can either use
(?:\(\d+(?:\.\d+)?,\d+(?:\.\d+)?\))+
or with global flag
\(\d+(?:\.\d+)?,\d+(?:\.\d+)?\)
First solution will match your pattern 1 or more times and returns a single match. The second will match your pattern only once. However with global flag you will get all matches as separate results.
Explanation:
(?: //begin non-capturing group
\( //match opening parentheses
\d+ //match 1 or more numbers
(?:\.\d+)? //optionally match a dot followed by 1 or more numbers
, //match a comma
\d+(?:\.\d+)? //same pattern as before comma
\) //match closing parentheses
)+ //close non-capturing group, match the group 1 or more times
Upvotes: 1
Reputation: 118
I think this should do the trick for your problem:
^(?:\(\d+(?:\.\d+)?,\d+(?:\.\d+)?\))+$
try it out
Currently I made all capturing groups non capturing groups since I was not sure about any specific subgroups you wanted to capture.
Upvotes: 0