【问题标题】:RegExp range of number (1 to 36)RegExp 的数字范围(1 到 36)
【发布时间】:2011-04-27 22:44:17
【问题描述】:

我搜索了很多,找不到这个 RegExp 的解决方案(我不得不说我对 Reg. Expressions 不是很有经验)。

我想测试一个介于 1 和 36 之间的数字,不包括 0 和 37 及以上。

到目前为止,我所拥有的几乎可以工作(它不接受 17、18、19、27、28、29)...

^[1-9]{1}$|^[1-3]{1}[0-6]{1}$|^36$;

有人可以帮帮我吗?

【问题讨论】:

    标签: javascript regex


    【解决方案1】:

    ^(?:[1-9]|[1-2][0-9]|3[0-6])$

    以下是它的细分:

    ^ = 行首

    (?:) 标记非捕获组 - 一种指定操作顺序而不保存匹配内容供以后使用的方法。

    [1-9] = 1-9 中的任何数字

    | = 或

    [1-2][0-9] = '1' 或 '2',后跟 0-9 之间的任意数字

    | = 或

    3[0-6] = '3',后跟 0-6 之间的任意数字。

    $ = 行尾

    正如@mu 所说的太短,使用整数比较会更容易,更有效。这是一个示例函数:

    function IsInRange(number)
    {
        return number > 0 && number < 37;
    }
    

    【讨论】:

    • 感谢解释,我真的需要它是一个正则表达式,否则我会用普通的旧javascript解决它:)
    • 此解决方案错误地匹配所有数字,如@9​​87654321@ 所示并在@mickmackusa 的答案中解释。
    • @FWDekker 谢谢,我相信我现在已经修好了。需要括号。
    【解决方案2】:

    试试这个:

    ^[1-9]$|^[1-2][0-9]$|^3[0-6]$
    

    (1 到 9 之间的所有 1 位数字,所有 1x 和 2x 数字,以及 30 到 36 之间的 3x 数字)。

    【讨论】:

      【解决方案3】:

      我不知道为什么所有的答案都会重复在每个条件之前和之后添加边界(^$)的错误。但你只需要这样做:

      ^([1-9]|[1-2][0-9]|3[0-6])$
      

      我还创建了一个 JavaScript/Node.js 库 to-regex-range,以简化像这样创建范围。

      【讨论】:

      • 此解决方案错误地匹配 37、38、39、40,如 this demo forked from qwerymk's demo 中所示并在 @mickmackusa 的答案中解释。
      • 缺少括号。固定的。 FWIW 您的评论导致 4 票反对。
      • 感谢您修复它。我不确定您在回答中“重复在每个条件之前和之后添加边界的错误”是什么意思。在您纠正之前,这不正是您的答案中缺少的吗?
      【解决方案4】:

      你知道\d,对吧?

      ^([1-9]|[12]\d|3[0-6])$
      

      在控制台试试这个:

      function test() {
          for(var i = 0; i < 100; i++) {
              if (/^([1-9]|[12]\d|3[0-6])$/.test(i.toString()) != (i >= 1 && i <=36)) {
                  document.write(i + "fail");
              }
                      else
                      document.write(i + "pass");
              document.write("<br/>");
          }
      }
      

      【讨论】:

      • 我看到 pass 的所有值。
      • @VitalyZdanevich 使用这个 var pat = /^[1-9]$|^[1-2]\d$|^3[0-6]$/; for(var i = 0; i "); }
      【解决方案5】:

      试试这个:

      /^[1-9]$|^[1-2]\d$|^3[0-6]$/
      

      DEMO

      【讨论】:

        【解决方案6】:

        试试^[1-9]$|^[1-2]\d$|^3[0-6]$

        【讨论】:

          【解决方案7】:

          纯粹出于学术原因,我将添加一个独特而准确的模式。

          /^(3[0-6]?|[12]\d?|[4-9])$/
          

          模式中有三个分支:

          1. 第一个匹配项:3、30、31、32、33、34、35、36
          2. 第二场比赛:1、2、10-19、20-29
          3. 第三场比赛:4、5、6、7、8、9

          如果在我的模式中存在效率优势(不是说这项任务可能会消耗大量资源——除非您要进行数千次这样的评估),那么归根结底就是没有多余的检查在模式中。

          它可能对正则表达式引擎没有任何影响,但我已经根据评估“努力”最少的分支(而不是自然的数字序列)对我的分支进行了排序。

          Harpo 的模式尽可能简短,但 [123] 是多个分支都满足的第一位数字匹配。

          @MichaelHoffmann 和 @jonschlinkert 的模式不正确,因为它们无法将必要的锚分配给每个分支。 这可以通过将所有分支包装在一个捕获组中来简洁地实现,但作为 @ninjalj,@ qwertymk 和 @amit_g 演示了,将锚点应用于每个分支同样准确。

          let txt = '<table border=1 cellpadding=4><tr><th>Number</th><th>Harpo</th><th>Michael Hoffmann</th><th>ninjalj</th><th>jonschlinkert</th><th>qwertymk</th><th>amit_g</th><th>mickmackusa</th></tr>',
              str,
              i;
              
          for (i = 0; i <= 40; ++i) {
            str = '' + i;
            txt += '<tr><td>' + i;
            txt += '</td><td>'  + /^([1-9]|[12]\d|3[0-6])$/.test(str);
            txt += '</td><td>' + /^[0-9]|[0-2][0-9]|3[0-6]$/.test(str);
            txt += '</td><td>' + /^[1-9]$|^[1-2][0-9]$|^3[0-6]$/.test(str);
            txt += '</td><td>' + /^[1-9]|[1-2][0-9]|3[0-6]$/.test(str);
            txt += '</td><td>' + /^[1-9]$|^[1-2]\d$|^3[0-6]$/.test(str);
            txt += '</td><td>' + /^[1-9]$|^[1-2]\d$|^3[0-6]$/.test(str);
            txt += '</td><td>' + /^(3[0-6]?|[12]\d?|[4-9])$/.test(str);
            txt += '</td></tr>';
          }
          txt = txt + '</table>';
          
          document.getElementById('test').innerHTML = txt;
          <div id="facts">Correct Pattern Designers: Harpo, ninjalj, qwertymk, amit_g, mickmackussa<br>Incorrect Patterns: Michael Hoffmann, jonschlinkert <br></div>
          <div id="test"></div>

          【讨论】:

          • @jonschlinkert 请阅读我的回答以了解您的模式为何不正确。
          • @MichaelHoffmann 请阅读我的回答以了解您的模式不正确的原因。
          【解决方案8】:

          检查在控制台中运行这个试试这个:

          var pat = /^[1-9]$|^[1-2]\d$|^3[0-6]$/;
          for(var i = 0; i < 100; i++) {
                  if (pat.test(i)) {
                      document.write(i + "pass");
                  }
                          else{
                          document.write(i + "fail");}
                  document.write("<br/>");
              }
          

          (1 到 36 之间的所有数字)。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-09-14
            • 2016-09-06
            • 1970-01-01
            • 2011-10-10
            • 2012-11-22
            • 2021-08-14
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多