2013-07-19 138 views
3

我需要一个正则表达式来匹配数字列表,而另一个匹配数字范围(在这两种情况下表达式永远不会失败)。范围应由一个数字,一个破折号和另一个数字(N-N)组成,而列表应由用逗号(N,N,N)分隔的数字组成。下面是一些例子。正则表达式匹配范围或数字列表

范围:

'1-10' => OK 
Whateverelse => NOK (e.g. '1-10 11-20') 

列表:

'1,2,3' => OK 
Whateverelse => NOK 

这里是我的两个正则表达式:

  1. [0-9] + [\ - ] [0-9] +
  2. ([0-9] + ,?)+

...但我和他们的几个问题...例如:

在评估'1-10'正则表达式2场比赛1 ...但它不应该匹配任何内容,因为该字符串不包含列表。

然后,评估'1-10 11-14'时,正则表达式1场比赛1-10 ...但因为字符串中包含的不仅仅是一个范围更不应该匹配任何。

我错过了什么?谢谢。

+0

'1,2,4'OK?你需要依次编号吗? – unlimit

+0

就像一个提示,你可以使用这个:http://regexpal.com/来测试正则表达式 –

+0

当你想要高级功能,它也取决于谁使用正则表达式的味道。 Perl有一组功能。 Awk另一个。 UNIX样式程序深深地依赖于正在使用的操作系统。 – Gilbert

回答

5

试试这个:

^((\d+-(\*|\d+))|((\*|\d+)-\d+)|((\d)(,\d)+))$ 

测试结果:

1-10   OK 
1,2,3  OK 
1-*   OK 
*-10   OK 
1,2,3 1-10 NOK 
1,2,3 2,3,4 NOK 
*-*   NOK 

正则表达式的可视化:

Visualization of the regex

编辑:增加了对wildcar根据OP的评论d *

+0

这个工程,正是我正在寻找...我刚刚添加了通配符的支持,以允许像'3 - \ *'或'\ * - 10'的表达式:^(([\\ * \ d] + - [\\ * \ d] +)|((\ d)(\ d)+))$;问题是这个正则表达式还匹配'\ * - \ *'等表达式(通配符可以在右边或左边,而不是两边)。 – j3d

+0

我假设你想要匹配'1- *,* -1'而不是'* - *'?看到我更新的答案。 – unlimit

+0

简单完美!非常感谢 :-) – j3d

1

首先,你应该使用anchors,以确保正则表达式匹配涵盖了整个字符串,而不是只是一个字符串:

^[0-9]+-[0-9]+$ 

然后,逗号是你的第二个正则表达式可选。试试这个:

^([0-9]+,)+[0-9]+$ 
0

您的问题最简单的解决方法是换一组额外的括号周围的第二个结果:

(([0-9]+,?)+) 

正如其他人所指出的,如果你正在服用的文字输入和多数民众赞成在整个输入你应该开始和结束它^$

^(([0-9]+,?)+)$ 

如果您正在搜索的文本,提取这些值的身体,那么你就不需要这一点。

括号表示匹配组。如果您将(?:添加到开头而不是(,也可以将内部支架标记为“非捕获组”。这会给你带来:

((?:[0-9]+,?)+) 

这将意味着唯一的捕获值是你想要的。你也可以忽略第二次捕获。

0

这一个是有点不同。它用于Procurve交换机上的端口。
^(((\d+)|(\d+-\d+))(,((\d+)|(\d+-\d+)))*)$
它在Perl中。

1     OK 
2     OK 
3     OK 
1-4     OK 
0-A     NOK 
83-91    OK 
14,15,16    OK 
14,20-25,91   OK 
a,b-c,5,5,5   NOK 
this-is,5,7,9  NOK 
9,8,1-2,1-7   OK 

我没有包括从上面的*。你(@unlimit)用了那个美妙的图表?

-E