匹配所有无序数字序列的正则表达式

Regex that matches all unordered sequence of numbers

我正在尝试构建一个仅匹配无序数字序列的正则表达式。我只能创建一个相反的正则表达式来匹配有序的数字序列,但我不知道如何反转它。这里是 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?)$

输入:

123
234567
0123456789
87654
321
985
346
320

预期匹配:

985
346
320

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

以前,如果您能找到更直观或更好的解决方案,我不会感到惊讶,(我认为正则表达式可能不是最好的方法)我仍然写了一个有效的方法。 所以这就是我想出的

[请原谅我的数学词汇,但这可能最好地解释了我处理这个问题的方式。如果太多了可以跳过..]

换句话说,无序序列是一个非单调序列挖掘,我们必须有一个局部最大值或最小值(在边缘旁边)。我们所需要的只是找到单调行为中断的单点(如果存在)。 简而言之,找到序列上升而不是下降,或者下降而不是上升的地方。

原样的正则表达式:

((\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*))

测试regex101

更具可读性

 // 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*))

如果您要测试您的输入,则不会匹配

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

所有顺序向后或向前


编辑:

这个正则表达式适用于检测未排序的序列,我将其解释为无序序列..结果问题意味着别的东西(我猜用户的意思是非连续序列)。我不知道在这种情况下该怎么办,删除这个答案感觉很浪费。如果其中一位管理员认为应该删除它,请随意删除..


试试这个正则表达式:

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

Click for Demo

解释:

  • ^ - 断言字符串的开头
  • (?=.*(?:1(?![02])|2(?![13])|3(?![24])|4(?![35])|5(?![46])|6(?![57])|7(?![68])|8(?![79])|9(?!8)|0(?!1))(?!$)) - 确保匹配不包含任何连续数字的前瞻(例如,如果有 2,则不应后跟 3 或a 1。此检查适用于所有数字)
  • \d+ - 匹配出现 1 次以上的数字
  • $ - 断言字符串结束