I'd like to match any string that contains only digits that are increasing or decreasing. This means that these strings would be matched:
123, 234567, 0123456789, 87654, 321
And these would not:
7891011, 1234566789, 987865, 134
I was looking for an answer and all I found was that this is not possible to be done using regex. However, I would like to do it in regex, otherwise it'd make a mess in the code.
Thanks for answers.
Technically it is possible with the use of lookaheads, but it won't look nice.
Logic for ascending pattern:
Example for 123:
Example for 134:
Regex to match ascending patterns:
^(?:0(?=1|$))?(?:1(?=2|$))?(?:2(?=3|$))?(?:3(?=4|$))?(?:4(?=5|$))?(?:5(?=6|$))?(?:6(?=7|$))?(?:7(?=8|$))?(?:8(?=9|$))?9?$

Debuggex Demo
Regex to match descending patterns:
^(?:9(?=8|$))?(?:8(?=7|$))?(?:7(?=6|$))?(?:6(?=5|$))?(?:5(?=4|$))?(?:4(?=3|$))?(?:3(?=2|$))?(?:2(?=1|$))?(?:1(?=0|$))?0?$

Debuggex Demo
Combined together:
^((?:0(?=1|$))?(?:1(?=2|$))?(?:2(?=3|$))?(?:3(?=4|$))?(?:4(?=5|$))?(?:5(?=6|$))?(?:6(?=7|$))?(?:7(?=8|$))?(?:8(?=9|$))?9?|(?:9(?=8|$))?(?:8(?=7|$))?(?:7(?=6|$))?(?:6(?=5|$))?(?:5(?=4|$))?(?:4(?=3|$))?(?:3(?=2|$))?(?:2(?=1|$))?(?:1(?=0|$))?0?)$

Debuggex Demo
Regex101 Demo
The code wouldn't be more of a mess than the regex to do this. Regular expressions are bad at math.
Something like this will do it:
bool IsSequentiallyIncreasing(string input)
{
char? lastDigit = null;
foreach (char c in input)
{
if (!c.IsDigit || (lastDigit != null && c != lastDigit + 1))
{
return false;
}
lastDigit = c;
}
return true;
}
So you walk over all characters in the string, and as soon as you encounter a non-digit or a digit that isn't the last digit + 1, you return false.
And do the same for decreasing, and you can simply call IsSequentiallyIncreasing(input) || IsSequentiallyDecreasing(input). I'll leave it up to you to add error handling and merge the two methods into one.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With