以小时为增量的正则表达式(RegEx)

以小时为增量的正则表达式(RegEx),regex,coldfusion,Regex,Coldfusion,我只需要接受符合这些规则的输入 0.25-24 增量为.25(.00、.25、.50、.75) 第一个数字不必是必需的 希望尾部的零是可选的 一些有效条目的示例: 0.25 .50 .5 一, 1.0 5.50 23.75 24(最大允许值) 更新:任何内容(空/空)也应视为有效 一些无效条目的示例: 0 .0 .00 0.0 0.00 24.25 -一, 我知道正则表达式是一种模式匹配语言,因此它对范围、小于和大于检查都不是很好。所以检查它是否小于或等于24意味着我必须找到一个模式,对吗?所以

我只需要接受符合这些规则的输入

  • 0.25-24
  • 增量为.25(.00、.25、.50、.75)
  • 第一个数字不必是必需的
  • 希望尾部的零是可选的
  • 一些有效条目的示例:

  • 0.25
  • .50
  • .5
  • 一,
  • 1.0
  • 5.50
  • 23.75
  • 24(最大允许值)
  • 更新:任何内容(空/空)也应视为有效
  • 一些无效条目的示例:

  • 0
  • .0
  • .00
  • 0.0
  • 0.00
  • 24.25
  • -一,
  • 我知道正则表达式是一种模式匹配语言,因此它对范围、小于和大于检查都不是很好。所以检查它是否小于或等于24意味着我必须找到一个模式,对吗?所以有24种可能的模式,这将使它成为一个长正则表达式,我理解正确吗?我可以使用ColdFusion进行检查,以确保它在0-24范围内。如果我在这部分使用ColdFusion,这还不是世界末日,但是如果它不会导致它太长的话,那么把它全部放到正则表达式中会很好。这就是我到目前为止所做的:

    ^\d{0,2}(\(0,00,25,5,50,75))$


    除了0-24范围检查或仅检查零之外,这几乎可以处理所有的检查。我会继续努力的,但任何帮助都将不胜感激。谢谢

    \d{0,2}
    更改为
    (?:1[0-9]?| 2[0-4]?|[3-9])?
    ,它将从1匹配到24(或不匹配)

    您还可以将第二部分简化为
    (?:\(?:00?| 25 | 50?| 75))?
    -您可以进一步简化为
    (?:\(?:[05]0?|[27]5))?
    ,但这可能会使意图过于模糊

    要排除24.25,您可能可以使用负前瞻
    (?!24\.[^0])
    来防止24.0或24.00以外的任何内容,但从主模式中排除24并在开始时包含24/24.0/24.00的特定检查可能更简单:

    (?x)
        # checks for 24
        ^24$|^24\.00?$
        |
        # integer part
        ^
        (?:1[0-9]?|2[0-3]?|[3-9]|0(?=\.[^0])|(?=\.[^0]))
        # decimal part
        (?:\.(?:00?|25|50?|75))?
        $
    
    这还包括对
    0(?=\.[^0])
    的检查,如果下一个字符是
    后跟非零字符(因此不允许使用0.0和0.00),则使用正向前瞻仅允许初始
    0

    (?x)
    标志允许忽略空白,允许在代码中使用可读的正则表达式(显然比将其全部压缩到一行更好),并且还允许使用
    #
    开始行注释来解释模式的部分。(文字空白和哈希可以用反斜杠转义,或通过哈希的
    \x23
    编码。)

    为了进行比较,这里有一种纯CFML的方法:

    IsNumeric(Num)
    AND Num GT 0
    AND Num LTE 24
    AND NOT find('.',Num*4)
    
    现在,你真的确定它作为正则表达式更好吗…

    ^([0-1]?[0-9]| 2[0-4])(\(0-00-25-5-50-75))$

    这意味着,如果缺少十位、0或1,则一的位置可以是0-9

    如果十位数是2,那么一位数可以是0-4

    第二部分很好,简单易读。它有一组额外的参数,但可以删除,将其简化为:

    ^([0-1]?[0-9]| 2[0-4])(\(0-00 | 25 | 5 | 50 | 75))?$

    您可以尝试这个正则表达式(细分):

    一行:

    ^(?:(?:[1-9]|1\d|2[0-3])(?:\.(?:[05]0?|[27]5))?|0?(?:\.(?:50?|[27]5))|24(?:\.00?)?)$
    

    我想它将匹配24.25,。。。还有。是的,我在发布后发现了这个问题,我刚刚更新以解决这个问题。嗯。。。只是注意到我错过了0.25分。。。在正则表达式中,冒号(:)的作用是什么?我不需要实时格式(显然12:75不是有效时间),而是用户输入时间的数字分数,例如12.75(相当于12小时45分钟)。没有文字冒号
    (?:
    是非捕获组-与
    相同,但不存储子匹配项。这个消息只是意味着没有捕获组(如我之前评论中的链接所述)——这没什么好担心的;如果您想提取匹配的子段或返回引用,则只需要捕获组——这两个都不是验证值所必需的。此正则表达式将考虑“0”“0”和“0”有效,这是无效的。看起来杰瑞的答案是最准确的,尽管它很复杂。这取决于你是否需要一个正则表达式中的所有内容,或者你是否愿意为0做一个单独的测试。使用
    2[0-4]
    将允许
    24.25
    等等。这个似乎也通过了我所有的测试,希望我能给出两个答案。谢谢。@gfrobenius别担心,谢谢你留下评论:)@gfrobenius顺便说一句,捕获组是特殊的组,比赛结束后可以使用。在这种情况下,只进行验证,因此不需要捕获组。否则,它们会占用您更多的可用内存!顺便问一下,允许空字符串通过可以吗?很好,是的,可以,你和Peter的答案允许
    {null}
    所以一切都很好。嗯,我的不应该匹配空字符串。。。我想我不完全理解CF如何处理regex=/哦,你是对的,你的没有,对不起,我错过了。是,空/空应该是有效的。如果你能调整你的答案,使之成为参考,我将不胜感激。这两个答案都非常有用。要允许任何模式使用空字符串,您可以在相关部分中使用前缀
    ^$
    -或防止空字符串更改为
    ^(!$)
    ^(?:(?:[1-9]|1\d|2[0-3])(?:\.(?:[05]0?|[27]5))?|0?(?:\.(?:50?|[27]5))|24(?:\.00?)?)$