【问题标题】:Regex that matches all unordered sequence of numbers匹配所有无序数字序列的正则表达式
【发布时间】:2017-12-24 22:08:11
【问题描述】:

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

【问题讨论】:

  • 需要用正则表达式解决这个问题吗?这不是一个很好的工作工具。
  • 很好的需求转储。你有什么自己的想法吗?
  • @slesh THIS 适用于您提供的输入。但是,我不确定它是否每次都有效。
  • @JohnKugelman,正则表达式的使用是任务的要求。
  • @Gurman,谢谢。似乎它有效。您能否将您的评论作为答案。

标签: regex regex-negation


【解决方案1】:

试试这个正则表达式:

^(?=.*(?: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,它后面不应该跟一个 31。这个检查适用于所有数字)
  • \d+ - 匹配出现 1 次以上的数字
  • $ - 断言字符串的结尾

【讨论】:

    【解决方案2】:

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

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

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

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

    正则表达式:

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

    所有的顺序都向后或向前


    编辑:

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


    【讨论】:

    • 您似乎没有正确理解任务。我需要匹配 985、346 和另一个无序的数字序列。所以你的正则表达式有点不同。
    • 我将“无序序列”解释为未排序的序列... -_-
    • 你的意思是非连续序列吗? '343456' 应该匹配吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-01-09
    • 1970-01-01
    • 2017-09-02
    • 2021-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多