I need to create a regular expression that only accepts numbers and addition and subtraction characters.
I've defined the single number and groups pattern by this way
([1-9][0-9]*)
I'm not able to add the definition for addition and subtraction characters.
I'd like to have all ok with something similar this example
Ex: 12 + 1 - 23 - 9 + 10
To achieve validation, I would recommend you tokenize it, but organize it by looking for an operator [+-]
first then the number. Once tokenized you can verify in code if all operations are valid and accumulate a resultant total.
Example
var data = "12 + 1 - 23 - 9 + 10";
var pattern = @"(?<Operator>[+-]*)\s*(?<Number>\d+)";
var tokens =
Regex.Matches(data, pattern)
.OfType<Match>()
.Select (mt => new
{
Operator = string.IsNullOrEmpty(mt.Groups["Operator"].Value)
? "+" // Default to '+' if not found. (First Number)
: mt.Groups["Operator"].Value,
Value = mt.Groups["Number"].Value
});
Result To Accumulate
Note it would also work if the numbers start out negative such as -12 + 1 - 23 - 9 + 10
result:
Frankly one could be adding negative numbers. Here is a pattern to handle the sign of the number and process the sign and the operator together to determine and positive or negative accumulation:
var data = "-12 + 1 + -2 - -3";
var pattern = @"(?<Operator>[+-]*)\s*(?<Sign>[-]*)\s*(?<Number>\d+)";
var tokens =
Regex.Matches(data, pattern)
.OfType<Match>()
.Select (mt => new
{
Operator = string.IsNullOrEmpty(mt.Groups["Operator"].Value)
? 1 // default to + if not found (First Number)
: mt.Groups["Operator"].Value == "-" ? 0 : 1,
Sign = string.IsNullOrEmpty(mt.Groups["Sign"].Value)
? 1 // default to positive
: 0,
Value = mt.Groups["Number"].Value
})
.Select (token => new
{
Postive = (((token.Operator & token.Sign) > 0) ||
((token.Operator + token.Sign) == 0))
? "+" : "-",
Value = token.Value
})
Result To Accumulate
Note that minus a -3
makes it a +3
when accumulated. ;-)
For completeness, here is a snapshot of the first Select
before the operator and sign determination of the following second Select
is done:
Which shows that two zeros signify two minuses, which need to be converted to a plus.