【问题标题】:Decimal number regular expression, where digit after decimal is optional十进制数正则表达式,其中小数点后的数字是可选的
【发布时间】:2012-08-20 11:13:50
【问题描述】:

我需要一个验证数字的正则表达式,但不需要小数点后的数字。 即。

123
123.
123.4

都是有效的

123..

无效

任何将不胜感激!

【问题讨论】:

标签: regex


【解决方案1】:

使用以下内容:

/^\d*\.?\d*$/
  • ^ - 行首;
  • \d* - 0 位或更多位;
  • \.? - 可选点(已转义,因为在正则表达式中,. 是一个特殊字符);
  • \d* - 0 位或更多位(小数部分);
  • $ - 行尾。

这允许 0.5 小数,而不需要前导零,例如 0.5

【讨论】:

  • @OrangeDog,您的原始匹配超出了预期。例如'cow3.45龙卷风' ;)
  • 它还匹配一个不是有效十进制数的点。更好的正则表达式是/^\d*\.?\d+$/,它将强制在小数点后输入一个数字。
  • @Chandranshu 它匹配一个空字符串,您的更改也可以解决。
  • @Chandranshu "不需要小数点后的数字"
  • 此解决方案不起作用。它需要小数,而 OP 明确表示:可选小数。
【解决方案2】:
/\d+\.?\d*/

一位或多位数字 (\d+)、可选句点 (\.?)、零位或多位数字 (\d*)。

根据您的使用情况或正则表达式引擎,您可能需要添加开始/结束行锚点:

/^\d+\.?\d*$/

Debuggex Demo

【讨论】:

  • 是的,但票数最高的答案是错误的,它同时匹配. 和空字符串。
  • @Gangnus 也没有说应该匹配“.digit”。如果他们想要那样,那么他们应该说。
  • @EqualityInTech 我很确定不是——它根本没有分组。
  • 嗯...我想我可能不像我想的那样完全理解邪恶的正则表达式。对不起。
  • @AlexanderRyanBaggett 这完全符合问题指定的内容。如您所见,它根本不包括-
【解决方案3】:

你需要一个像下面这样的正则表达式才能正确地做到这一点:

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

带有空格的相同表达式,使用扩展修饰符(Perl 支持):

/^  [+-]? ( (\d+ (\.\d*)?)  |  (\.\d+) ) $/x

或使用 cmets:

/^           # Beginning of string
 [+-]?       # Optional plus or minus character
 (           # Followed by either:
   (           #   Start of first option
     \d+       #   One or more digits
     (\.\d*)?  #   Optionally followed by: one decimal point and zero or more digits
   )           #   End of first option
   |           # or
   (\.\d+)     #   One decimal point followed by one or more digits
 )           # End of grouping of the OR options
 $           # End of string (i.e. no extra characters remaining)
 /x          # Extended modifier (allows whitespace & comments in regular expression)

例如会匹配:

  • 123
  • 23.45
  • 34.
  • .45
  • -123
  • -273.15
  • -42.
  • -.45
  • +516
  • +9.8
  • +2.
  • +.5

并且会拒绝这些非数字:

  • 。 (一位小数)
  • -。 (负小数点)
  • +。 (加小数点)
  • (空字符串)

更简单的解决方案可能会错误地拒绝有效数字或匹配这些非数字。

【讨论】:

  • 最好,因为它匹配一个数字后跟一个句点 (42.)。但是有一个错误/误报,因为它与此匹配:3....3 可以通过添加两个括号来强制执行 ^$ 开始和结束字符来修复:/^([+-]?(\d+(\ .\d*)?)|(\.\d+))$/
  • 谢谢皮特,很好。答案现在已得到纠正,通过添加额外的括号使其行为符合预期。现在写成^A?(B|C)$。以前,它被写成^A?B|C$ 这实际上意味着(^A?B)|(C$) 这是不正确的。注意:^(A?B|C)$ 也不正确,因为它实际上表示^((A?B)|(C))$ 不会匹配“+.5”。
  • 这是最好的答案。其他答案不能处理所有情况。我自己做了类似的事情,除了我使用前瞻来处理丢失数字的情况: /^[+-]?(?=\d|\.\d)\d*(\.\d*)?$ /
  • 这是这里唯一正确的正则表达式。但有些人会不同意“34.”。我会在第二个 d 之后建议 + 而不是 *
  • 这也匹配 0000.2,这可能不是我们想要的。
【解决方案4】:

这符合所有要求:

^\d+(\.\d+)?$

【讨论】:

  • 对我来说这是最好的答案,因为字符串:“4”。 (例如)至少在 ruby​​ 语言中不是有效数字。但是,投票最多的答案接受“4”。作为数字正则表达式,这是错误的。
【解决方案5】:

试试这个正则表达式:

\d+\.?\d*

\d+ 可选小数点前的数字
.?可选小数(可选由于 ? 量词)
\d* 小数点后的可选数字

【讨论】:

  • 不,那个不匹配123.
  • 感谢您的来信。修改了我的正则表达式。
  • 确实如此,但现在您只是将其编辑成其他人已经发布的内容。考虑删除另一个“正确”答案。
  • @Edison 斜线是正则表达式分隔符:不是模式本身的一部分。您将看到许多包含这些分隔符的答案。
  • 嗯,好的。谢谢。无论如何,对于像我这样不知道的人来说,答案很好,否则我不会知道。
【解决方案6】:

我最终使用了以下内容:

^\d*\.?\d+$

这使得以下内容无效:

.
3.

【讨论】:

  • 您可能需要斜杠,具体取决于您使用的语言。例如:/^\d*\.?\d+$/
【解决方案7】:

你可以用这个:

^\d+(\.\d)?\d*$

匹配:
11
11.1
0.2

不匹配:
.2
2.
2.6.9

【讨论】:

  • 谢谢,很简单,符合我的需要
【解决方案8】:

这就是我所做的。它比上述任何一个都更严格(并且比某些更正确):

^0$|^[1-9]\d*$|^\.\d+$|^0\.\d*$|^[1-9]\d*\.\d*$

通过的字符串:

0
0.
1
123
123.
123.4
.0
.0123
.123
0.123
1.234
12.34

失败的字符串:

.
00000
01
.0.
..
00.123
02.134

【讨论】:

    【解决方案9】:
    ^[+-]?(([1-9][0-9]*)?[0-9](\.[0-9]*)?|\.[0-9]+)$
    

    应该反映人们通常认为的格式良好的十进制数。

    小数点前的数字可以是单个数字,这种情况下可以是0到9,也可以是多个数字,这种情况下不能以0开头。

    如果小数点之前有任何数字,那么小数点和它后面的数字是可选的。否则,必须存在小数点后跟至少一位数字。请注意,小数点后允许有多个尾随 0。

    grep -E '^[+-]?(([1-9][0-9]*)?[0-9](\.[0-9]*)?|\.[0-9]+)$'
    

    正确匹配以下内容:

    9
    0
    10
    10.
    0.
    0.0
    0.100
    0.10
    0.01
    10.0
    10.10
    .0
    .1
    .00
    .100
    .001
    

    以及它们的签名等价物,而它拒绝以下内容:

    .
    00
    01
    00.0
    01.3
    

    及其签名的等价物,以及空字符串。

    【讨论】:

      【解决方案10】:

      什么语言? Perl 风格:^\d+(\.\d*)?$

      【讨论】:

        【解决方案11】:

        您所问的问题已经得到解答,因此如果输入可选的小数点,这只是对于那些只想要 2 位小数的人的附加信息:

        ^\d+(\.\d{2})?$
        

        ^ : 字符串的开头
        \d : 一个数字(等于 [0-9])
        + :一次且无限次

        正在捕获组 (.\d{2})?
        ? : 零次和一次 . : 字符 .
        \d : 一个数字(等于 [0-9])
        {2}:正好 2 次
        $ : 字符串结束

        1:匹配
        123:匹配
        123.00 : 比赛
        123. : 不匹配
        123..:不匹配
        123.0:不匹配
        123.000 : 不匹配
        123.00.00 : 不匹配

        【讨论】:

        • 这是否匹配负数?
        • @AlexanderRyanBaggett 你需要检查负号,所以它是:^-?\d+(\.\d{2})?$
        【解决方案12】:
        (?<![^d])\d+(?:\.\d+)?(?![^d])
        

        干净简单。

        这使用后缀和前缀、RegEx 功能。

        IsMatch 条件直接返回真 - 假

        【讨论】:

          【解决方案13】:
          ^\d+(()|(\.\d+)?)$
          

          想出了这个。允许整数和小数,但如果您决定输入小数,则强制使用完整的小数(前导和尾随数字)。

          【讨论】:

            【解决方案14】:

            试试这个。 ^[0-9]\d{0,9}(\.\d{1,3})?%?$ 它已经过测试并为我工作。

            【讨论】:

              【解决方案15】:

              正则表达式:

              ^\d+((.)|(.\d{0,1})?)$
              

              如果您想允许多个数字,请使用\d+ 而不是\d{0,1},如果您想在昏迷后最多允许两个数字,请使用\d{0,2} 而不是\d{0,1}。请参阅下面的示例以供参考:

              ^\d+((.)|(.\d{0,2})?)$
              

              ^\d+((.)|(.\d+)?)$
              

              说明

              `^` 在行首断言位置
              `\d` 匹配一个数字(相当于 `[0-9]`)
              `+` 匹配前一个令牌一次到无限次,尽可能多次,根据需要返回(贪婪)
              第一个捕获组 `((.)|(.\d{0,1})?)`
              第一种选择`(.)`
              第二捕获组`(.)`
              `.` 匹配任何字符(行终止符除外)
              第二种选择 `(.\d{0,1})?`
              第三个捕获组 `(.\d{0,1})?`
              `?` 匹配前一个标记 0 到 1 次,尽可能多次,根据需要返回(贪婪)
              `.` 匹配任何字符(行终止符除外)
              `\d` 匹配一个数字(相当于 [0-9])
              `{0,1}` 匹配前一个令牌 0 到 1 次,尽可能多次,根据需要返回(贪婪)
              `$` 在行尾断言位置

              沙盒

              在这里玩正则表达式:https://regex101.com/

              【讨论】:

              • 感谢您详细解释的答案。我想要 3 位小数用于道路桩号实施,这很有帮助。
              【解决方案16】:

              在 Perl 中,使用 Regexp::Common 可以为您的特定数字格式组装一个经过微调的正则表达式。如果您不使用 Perl,生成的正则表达式通常仍然可以被其他语言使用。

              在 Regexp::Common::Number: 中打印生成示例正则表达式的结果:

              $ perl -MRegexp::Common=number -E 'say $RE{num}{int}'
              (?:(?:[-+]?)(?:[0123456789]+))
              
              $ perl -MRegexp::Common=number -E 'say $RE{num}{real}'
              (?:(?i)(?:[-+]?)(?:(?=[.]?[0123456789])(?:[0123456789]*)(?:(?:[.])(?:[0123456789]{0,}))?)(?:(?:[E])(?:(?:[-+]?)(?:[0123456789]+))|))
              
              $ perl -MRegexp::Common=number -E 'say $RE{num}{real}{-base=>16}'
              (?:(?i)(?:[-+]?)(?:(?=[.]?[0123456789ABCDEF])(?:[0123456789ABCDEF]*)(?:(?:[.])(?:[0123456789ABCDEF]{0,}))?)(?:(?:[G])(?:(?:[-+]?)(?:[0123456789ABCDEF]+))|))
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2014-03-05
                • 2010-11-01
                • 1970-01-01
                • 2013-01-11
                • 1970-01-01
                相关资源
                最近更新 更多