正则表达式,其中字符串的一部分必须在0到100之间

时间:2009-12-15 18:50:46

标签: c# regex numbers

我需要验证序列号。为此我们在C#中使用正则表达式,而某个产品,序列号的一部分是“午夜以来的秒”。一天有86400秒,但如何在此字符串中将其验证为5位数字?:

654984051-86400-231324

我无法使用这个概念:

[0-8][0-6][0-4][0-0][0-0]

因为那时86399无效。我怎么能克服这个?我想要这样的东西:

[00000-86400]

更新
我想清楚地表明我已经意识到 - 并且同意 - “当有一种更简单的方式时,不要使用正则表达式”思想学习。 Jason's answer正是我想要的,但是这个序列号验证适用于通过我们系统的所有序列号 - 目前还没有针对这些特定序列号的自定义验证码。 在这种情况下我有充分的理由寻找正则表达式解决方案。

当然,如果没有,那么这对于这些特定产品的自定义验证的情况是不可否认的,但我想在使用需要更改代码的解决方案之前完全探索这个途径。

7 个答案:

答案 0 :(得分:10)

不要使用正则表达式?如果你正在努力想出正则表达式来解析它,那就说它可能太复杂而你应该找到更简单的东西。当一个简单的

时,我认为在这里使用正则表达式绝对没有任何好处
int value;
if(!Int32.TryParse(s, out value)) {
    throw new ArgumentException();
}
if(value < 0 || value > 86400) {
    throw new ArgumentOutOfRangeException();
}

工作得很好。它非常清晰,易于维护。

答案 1 :(得分:7)

你不想尝试使用正则表达式,你会得到一些难以理解,笨拙和难以修改的东西(有人可能会建议一个:)。你想要做的是使用正则表达式匹配字符串以确保它包含你想要的格式的数字,然后拉出一个匹配的组并使用算术比较检查范围。例如,在伪代码中:

match regex /(\d+)-(\d+)-(\d+)/
serial = capture group 2
if serial >= 0 and serial <= 86400 then
    // serial is valid
end if

答案 2 :(得分:6)

使用标准的“这不是特别重复问题”的警告,

[0-7]\d{4}|8[0-5]\d{3}|86[0-3]\d{2}|86400 

答案 3 :(得分:6)

生成正则表达式以匹配任意数字范围 http://utilitymill.com/utility/Regex_For_Range

产生以下正则表达式:

\b0*([0-9]{1,4}|[1-7][0-9]{4}|8[0-5][0-9]{3}|86[0-3][0-9]{2}|86400)\b

输出描述:

First, break into equal length ranges:
  0 - 9
  10 - 99
  100 - 999
  1000 - 9999
  10000 - 86400

Second, break into ranges that yield simple regexes:
  0 - 9
  10 - 99
  100 - 999
  1000 - 9999
  10000 - 79999
  80000 - 85999
  86000 - 86399
  86400 - 86400

Turn each range into a regex:
  [0-9]
  [1-9][0-9]
  [1-9][0-9]{2}
  [1-9][0-9]{3}
  [1-7][0-9]{4}
  8[0-5][0-9]{3}
  86[0-3][0-9]{2}
  86400

Collapse adjacent powers of 10:
  [0-9]{1,4}
  [1-7][0-9]{4}
  8[0-5][0-9]{3}
  86[0-3][0-9]{2}
  86400

Combining the regexes above yields:
  0*([0-9]{1,4}|[1-7][0-9]{4}|8[0-5][0-9]{3}|86[0-3][0-9]{2}|86400)

在此测试: http://osteele.com/tools/rework/

答案 4 :(得分:0)

如果你真的需要一个纯正则表达式解决方案,我相信这会有效,尽管其他海报只是验证它们是数字然后使用匹配组来验证实际数字。

([0-7][0-9]{4}) | (8[0-5][0-9]{3}) | (86[0-3][0-9]{2}) | (86400)

答案 5 :(得分:0)

我会使用正则表达式结合一些.NET代码来实现这一目标。纯正的正则表达式解决方案对于处理大量范围来说并不容易或有效。

但这会:

Regex myRegex = new Regex(@"\d{9}-(\d{5})-\d{6}");
String value = myRegex.Replace(@"654984051-86400-231324", "$1");

在这种情况下,这将获取值86400。然后根据Jason的回答,你只是检查捕获的数字是否在0到86400之间。

答案 6 :(得分:-1)

我不相信这在正则表达式中是可行的,因为这不是可以作为常规语言的一部分进行检查的东西。换句话说,有限状态自动机机器无法识别此字符串,因此正则表达式也不能识别。

编辑:这可以通过正则表达式识别,但不能以优雅的方式识别。它需要一个怪物链(例如:00000|00001|000020{1,5}|0{1,4}1|0{1,4}2)。对我来说,不得不列举如此大量的可能性,这清楚地表明,虽然技术上可行,但它不可行或不易管理。