2
votes

I am trying to build a regexp that matches only to disordered sequence of numbers. I could created only an opposite regex that matches an ordered sequence of numbers, but I couldn't figure out how to invert it. Here is demo.

^((?: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?)$

Input:

123
234567
0123456789
87654
321
985
346
320

Expected matches:

985
346
320
2
Do you need to solve this with a regex? It's not a very good tool for the job.John Kugelman
Nice requirements dump. Have you got any ideas of your own?Mad Physicist
@slesh THIS works for the inputs provided by you. But, I am not sure if it will work everytime.Gurmanjot Singh
@JohnKugelman, the usage of regex is requirement of task.slesh
@Gurman, thanks. It seems that it works. Could you please get your comment as answer.slesh

2 Answers

2
votes

Try this regex:

^(?=.*(?:1(?![02])|2(?![13])|3(?![24])|4(?![35])|5(?![46])|6(?![57])|7(?![68])|8(?![79])|9(?!8)|0(?!1))(?!$))\d+$

Click for Demo

Explanation:

  • ^ - asserts the start of the string
  • (?=.*(?:1(?![02])|2(?![13])|3(?![24])|4(?![35])|5(?![46])|6(?![57])|7(?![68])|8(?![79])|9(?!8)|0(?!1))(?!$)) - Lookahead to make sure that match does not contain any consecutive numbers(For eg, If there is a 2, it should not be followed by a 3 or a 1. This check is applied for all the numbers)
  • \d+ - matches 1+ occurrences of a digit
  • $ - asserts the end of the string
0
votes

I am trying to build a regexp that matches only to disordered sequence of numbers.

before, i won't be surprised if you could find a more intuitive or better solution, (and to my opinion regex might not be the best way) still i've written one that works. so this is what i come up with

[please excuse my for the math words, but this might explain best the way i approach this. you can skip that if it's too much ..]

a disordered sequence in other words, is a non monotonic sequence minning, that we must have a local maximum or minimum (beside the edges). all we need is to find a single point (if exists) where the monotonic behavior breaks. in simple words find where the sequence go up than down, or, down and than up.

the regex as is :

((\d*[1-9]\d*)[0](\d*[1-9]\d*)|(\d*[2-9]\d*)[1](\d*[2-9]\d*)|(\d*[3-9]\d*)[2]    (\d*[3-9]\d*)|(\d*[4-9]\d*)[3](\d*[4-9]\d*)|(\d*[5-9]\d*)[4](\d*[5-9]\d*)|(\d*[6-9]\d*)[5](\d*[6-9]\d*)|(\d*[7-9]\d*)[6](\d*[7-9]\d*)|(\d*[8-9]\d*)[7](\d*[8-9]\d*)|(\d*[9]\d*)[8](\d*[9]\d*))|((\d*[0-8]\d*)[9](\d*[0-8]\d*)|(\d*[0-7]\d*)[8](\d*[0-7]\d*)|(\d*[0-6]\d*)[7](\d*[0-6]\d*)|(\d*[0-5]\d*)[6](\d*[0-5]\d*)|(\d*[0-4]\d*)[5](\d*[0-4]\d*)|(\d*[0-3]\d*)[4](\d*[0-3]\d*)|(\d*[0-2]\d*)[3](\d*[0-2]\d*)|(\d*[0-1]\d*)[2](\d*[0-1]\d*)|(\d*[0]\d*)[1](\d*[0]\d*))

test on regex101

more readable

 // found min 
 ((\d*[1-9]\d*)[0](\d*[1-9]\d*)|(\d*[2-9]\d*)[1](\d*[2-9]\d*)|
  (\d*[3-9]\d*)[2](\d*[3-9]\d*)|(\d*[4-9]\d*)[3](\d*[4-9]\d*)|
  (\d*[5-9]\d*)[4](\d*[5-9]\d*)|(\d*[6-9]\d*)[5](\d*[6-9]\d*)|
  (\d*[7-9]\d*)[6](\d*[7-9]\d*)|(\d*[8-9]\d*)[7](\d*[8-9]\d*)|
  (\d*[9]\d*)[8](\d*[9]\d*))|
 // found max 
 ((\d*[0-8]\d*)[9](\d*[0-8]\d*)|(\d*[0-7]\d*)[8](\d*[0-7]\d*)|
  (\d*[0-6]\d*)[7](\d*[0-6]\d*)|(\d*[0-5]\d*)[6](\d*[0-5]\d*)|
  (\d*[0-4]\d*)[5](\d*[0-4]\d*)|(\d*[0-3]\d*)[4](\d*[0-3]\d*)|
  (\d*[0-2]\d*)[3](\d*[0-2]\d*)|(\d*[0-1]\d*)[2](\d*[0-1]\d*)|
  (\d*[0]\d*)[1](\d*[0]\d*))

if you will test your inputs non will match

123, 234567, 0123456789, 87654, 321, 985, 346, 320

thay all order backward or forward


Edit :

this regex good for detect an unsorted sequences, which i interpreted as an unordered sequences.. it turn out the question meant something else (i guess the user meant to non consecutive sequence). i dont know what to do in this situation ,and it feel like a waste to delete this answer. if one of the admin think it should be deleted feel free to do so ..