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

时间:2017-12-24 22:08:12

标签: regex regex-negation

我正在尝试构建一个仅与无序数字序列匹配的正则表达式。我只能创建一个匹配有序数字序列的相反正则表达式,但我无法弄清楚如何反转它。这是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

2 个答案:

答案 0 :(得分:2)

试试这个正则表达式:

^(?=.*(?: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或{ {1}}。此检查适用于所有数字)
  • 1 - 匹配1位以上的数字
  • \d+ - 断言字符串的结尾

答案 1 :(得分:0)

  

我正在尝试构建一个仅与无序数字序列匹配的正则表达式。

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

[请原谅我的数学词,但这可能最好地解释了我的方法。你可以跳过它,如果它太多了.. ]

换句话说,无序序列是一个非单调序列,我们必须有一个局部最大值或最小值(在边缘旁边)。我们所需要的只是找到单调行为中断的单个点(如果存在)。 用简单的单词来查找顺序上升的位置,而不是向下,或向下,而不是向上。

正则表达式:

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

所有顺序向后或向前

修改:

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