【问题标题】:Regex for validating ratios such as Y39.29/28h用于验证比率的正则表达式,例如 Y39.29/28h
【发布时间】:2013-12-21 23:30:41
【问题描述】:

我正在尝试编写一个必须遵守以下规则的正则表达式:

Y120.001/100.232k
↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑
| | | | | | | | This k may be any letter, is not required
| | | | | | | Another number if there was a dot
| | | | | | A dot, not required
| | | | | A number with at least one digit, not required if a letter follows
| | | | Always a slash
| | | If there's a dot, digits can follow
| | A dot, not required
| A number, at least one digit
Always Y

这些字符串应该可以工作:

  • Y120.001/1k
  • Y1/小时
  • Y2039/100
  • Y29/47.0

这些不应该工作:

  • x203/493s(开头不是 Y)
  • Y/39x(Y 后面没有数字)
  • Y83839(下半部分缺失)
  • Y78/29(最后一个字母丢失)

这是我早期的尝试,但在 PHP 中不起作用:

/^\$*(\d)*(.*(\d))\/*(.*(\d))*.$

【问题讨论】:

  • 你写的是最后一个字母不需要,第二个数字也不需要,这是否意味着 Y123/ 是一个有效的字符串?
  • @klarki 关于它说“如果后面有字母则不需要”的数字。我的理解是这样的:你可以不带字母或不带数字,但不能不带两者,即Y123/1 -> 有效,Y123/x -> 有效,Y123/ -> 无效。
  • 这个有什么解决办法吗..stackoverflow.com/questions/34327142/…

标签: javascript php regex


【解决方案1】:

这个模式应该可以工作:

^Y\d+(\.\d*)?/(\d+(\.\d*)?[a-z]?|[a-z])$

Demonstration

【讨论】:

    【解决方案2】:

    在 JavaScript 中

    re=/^Y\d+(\.\d+)?\/([a-z]$|\d+(\.\d+)?[a-z]?$)/
    
    "Y120.001/1k Y1/h Y2039/100 Y29/47.0".split(" ").map(function(s) { return re.test(s) })
    > [true, true, true, true]
    
    "x203/493s Y/39x Y83839 Y78/29".split(" ").map(function(s) { return re.test(s) })
    > [false, false, false, true]
    

    这确实接受Y78/29,因为尾随字母是可选的。

    【讨论】:

      【解决方案3】:

      经过多次迭代以纠正评论的缺点:

      /^Y\d+(?:\.\d+)?\/(?:(?:\d+(?:\.\d+)?)[A-Za-z]?|[A-Za-z])$/
      

      Demonstration

      旧答案:

      这是一个运行良好的完全特定版本。

      /^Y\d+(?:\.\d+)?\/(\d+(?:\.\d+)?)?[A-Za-z]?$/
      

      jsfiddle中的后续测试编辑

      【讨论】:

      • 我更新了一个小的语法更改以允许 'Y1/h' 匹配。
      • Nice :) 新版也匹配Y1/,好像违规了。
      • 在演示中添加了针对几个边缘案例的更多测试。规则是否使 Y1./12.1k 有效?
      【解决方案4】:
      ^Y\d+\.?\d*/((\d+\.?\d*)[a-zA-Z]?|(\d+\.?\d*)?[a-zA-Z])$
      

      你可以从here查看正则表达式的解释。

      【讨论】:

      • 这也匹配Y1/,它没有作为示例输入给出,但它似乎违反了规则。
      • 匹配Y120./1k also(后面没有数字的点)!
      【解决方案5】:

      如果我了解您的规范的细微差别

      \bY\d+(?:\.\d*)?/(?:[A-Za-z]|(?:\d+(?:\.\d+)?[A-Za-z]?))\b
      

      我理解您的规范包括,如果存在第一个点,则以下数字是可选的;但如果存在第二个点,则必须至少有一个以下数字。其他人似乎对您的这部分要求有不同的解释。

      【讨论】:

        【解决方案6】:

        这种模式应该可以工作Y[\d.]+\/[\d.]*[a-z]?Demo

        【讨论】:

          【解决方案7】:

          下面的呢?

          var r = /^Y\d+(\.\d+)?\/(\d+(\.\d+)?|(\d+(\.\d+)?)?[A-Za-z])$/;
          console.log(true  === r.test('Y120.001/1k')); // true
          console.log(true  === r.test('Y1/h'));        // true
          console.log(true  === r.test('Y2039/100'));   // true
          console.log(true  === r.test('Y29/47.0'));    // true
          console.log(false === r.test('x203/493s'));   // true
          console.log(false === r.test('Y/39x'));       // true
          console.log(false === r.test('Y83839'));      // true
          

          【讨论】:

            【解决方案8】:

            试试这个:

            /Y\d+\.?\d*\/\d+\.?\d*\w?/
            

            【讨论】:

            • 这会因“Y1/h”(问题中提到)和“Y123/k”(根据所述规则有效)而失败。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2020-10-09
            • 1970-01-01
            • 2011-06-17
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多