【问题标题】:Regular Expression almost perfect for a Numeric Value正则表达式对于数值来说几乎是完美的
【发布时间】:2014-04-28 20:27:29
【问题描述】:

我有这个正则表达式几乎完美......它似乎可以处理所有除了一个以负号和小数开头的数字。所以如果我输入:

-.2

我收到一个错误 -

这是我的正则表达式——我测试过的所有其他东西都运行良好......

^(\+|-)?[0-9]{1,11}?(?:\.[0-9]{1,4})?$

这允许:

  • 最多 11 位数字(990 亿)
  • 正数或负数
  • 最多 4 位小数(可选)
  • 小数点前的前导 0 是可选的 - 仅适用于正数

这些都有效:

-0.2345
-10
12
.125
0.1245
5.555
25000000000 (aka 25 Billion)
25000000000.25 

这些不起作用:

-.2
-.421

【问题讨论】:

  • @JohnBupit - .125 在他的工作清单中
  • 但不能:".125".match(/^(\+|-)?[0-9]{1,11}?(?:\.[0-9]{1,4})?$/)
  • 另一个错误? 100000000000.0001 应该合法吗?
  • @Hogan - 不......我不希望它超过 1000 亿。感谢所有人...有人发布了以下内容然后将其删除...(它似乎工作得很好!!感谢神秘的助手。我将其投入生产并继续我的下一个问题...感谢所有人快速而精彩的回复!!:^(\+|-)?\.?[0-9]{1,11}?(?:\.[0-9]{1,4})?$跨度>
  • @DanB - 这个答案是错误的,它会允许像.2.2 这样的非法号码,这就是他删除它的原因(我的评论)。请使用约翰的答案或我的答案。它们仍然不会限制在 1000 亿以下,但它们会更好。

标签: c# regex


【解决方案1】:

正则表达式可能很昂贵...为什么不使用 Decimal.Parse 或 Float.parse?

您当前的实现将永远无法使用备用数字样式,例如 European where 。 (dot) 和 , (comma) 互换...而 Decimal.Parse 将:

string stringValue = "45.889,33";
CultureInfo currentCulture = Thread.CurrentCulture; //set this way up in the execution chain
decimal thenumber = Decimal.Parse(stringValue, currentCulture);
//thenumber = 45889.33 in us-en display format.

数值解析不是正则表达式的好应用,IMO。

【讨论】:

  • 你的答案也比正则表达式更容易理解——因此代码更容易维护
  • @enorl76 - 如果用户输入 45,889.33 然后我使用“Decimal.Parse(stringValue, french_culture);”会发生什么在那种情况下它不会产生错误吗?那时我需要像 Decimal.TryParse() 这样的东西吗? (我不关心在这种情况下在欧洲使用它,但想知道我自己的启发。
  • @DanB:如果当前的文化是 en-US,那么用户的输入将被正确输入。如果当前的文化是 fr-FR,那么“45.889,33”也可以正确输入。如果您想要“验证”,那么是的,Decimal.TryParse 会通知您关于当前文化的 NumericalFormat 规范的有效性。
【解决方案2】:

试试这个:

^(\+|-)?[0-9]{0,11}?(?:\.[0-9]{1,4})?$

更新:

上述正则表达式接受字符串+-(空字符串)。您可以使用 <em>lookahead</em> 来限制这些。前瞻确保+- 符号后必须有一个字符。

正确的解决方法是:

^(\+|-)?(?=.{1})[0-9]{0,11}(?:\.[0-9]{1,4})?$

A working example:

接受的字符串:

-0.2345
-10
12
.125
0.1245
5.555
-.2
-.421

不接受字符串:

100000000000.0001
+
-

123456789012
1111111111.12345
+1.11.1
-2.

【讨论】:

  • 不,不是。在{0, 11}更改。
  • 使用提供的数据,这似乎可以在 regexpal.com 上正常工作。
【解决方案3】:

我的 $.02

 ^(\+|-)?([0-9]{1,11}|)?(?:\.[0-9]{1,4})?$

【讨论】:

  • 这不匹配-a.24吗? (我没有测试过)
  • [0-9] 限制为位数。
  • 哦,我明白我在哪里看错了。 |) 是“或无”,而不是“或任何”。
  • 为什么 "|)"(“或无”)后跟 "?"(0 或 1),因为它们实际上是在执行一样?而且,我认为如果将 "{1,11}" 更改为 "{0,11}",则可以同时删除 "|""?" ,所以最终将是:^(\+|-)?([0-9]{0,11})(?:\.[0-9]{1,4})?$
  • @KevinFegan - 试试看。
【解决方案4】:

这个坏孩子怎么样:

^(\+|-)?([0-9]{1,11}?|)(?:\.[0-9]{1,4})?$

似乎有效 =)

【讨论】:

  • ** 是什么意思?我以前从未见过。或者这是一种大胆的尝试?您不能在代码块内格式化文本。
  • @Bobson - 我认为这是为了显示变化,但在正则表达式中很奇怪
  • 它在预览中以粗体显示。我会删除它们
【解决方案5】:

关键字:0 仅对 POSITIVE 数字是可选的。

你需要单独的正面和负面陈述。

^(((\+?[0-9]{0,11})|(-[0-9]{1,11}))(?:\.[0-9]{1,4})*)$

【讨论】:

  • 有人发布了以下内容,然后立即将其删除——它似乎工作得很好......我想给他点赞,但他的答案不见了...... ^(\+ |-)?\.?[0-9]{1,11}?(?:\.[0-9]{1,4})?$
  • 您接受的答案不会强制在负数的小数点前加 0。这个正则表达式现在可以正常工作了。
  • 感谢@Hogan,我发现答案不太正确...它允许小数点后2位...我已经接受了“John Bupit”的答案...看起来很完美...由于截止日期没有时间测试休息......但感谢您的帮助!
  • 哪个表达式允许两位小数?我的没有,而且仍然是这里唯一一个不允许没有前导 0 的负数的表达式。
【解决方案6】:

您的所有问题都可以在正确的位置使用word boundary 来解决:

^(?:\+|-\b)?[0-9]{0,11}(?:\.[0-9]{1,4})?\b$
  • {1,11} 更改为 {0,11} 以允许小数点前有零位。
  • 减号后的\b 不允许小数点紧邻它。
  • 最后的\b 不允许"+""-" 作为整个字符串。

工作示例(改编自 John):http://rubular.com/r/c7YLR25r3i

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-30
    • 1970-01-01
    • 2018-09-21
    相关资源
    最近更新 更多