2013-10-03 93 views
-1

你怎么写,从-214748.00-214748214748.00相匹配的货币的数值范围内的正则表达式?正则表达式匹配表达式货币数值范围

我试过这个,但没有工作。

^[-]?[0-9]{1,214748 }(?:\\.[0-9]{2})?$ 
+3

我要问,如果你有一些数字,为什么你是使用正则表达式? – drobert

+0

我的要求是限定人数,如果超过上限,然后我需要抛出一个异常 –

+0

这是最绝对不是正则表达式的工作。你会用螺丝刀敲钉子吗?没有容易的方式来写一个正则表达式来验证的数处于范围,除非范围限制是10次幂(即-100000 <= X <= 100000) –

回答

5

Nonono。你正在使用错误的工具来完成这项工作。正则表达式只是一个文本处理工具。解释文本的含义是不好的。在识别需要处理的文本的语义时,这就是正则表达式不好的地方。

你应该使用简单的语言工具和操作员来完成这项工作。除此之外,如果你处理的货币,避免使用doublefloat。它们没有足够的精度来准确地表示所有的浮点数。改为使用BigDecimal


警告:请,永远不要用这个这类问题:
注:这不处理浮点数。

既然你坚持了这么多,我想出了下面的正则表达式,其适用于某些输入我测试过。我想这将很好地工作在给定范围内的任何整数值:

"-?(\\d{1,5}|1\\d{5}|2(?:0\\d{4}|1(?:[0-3]\\d{3}|4(?:[0-6]\\d{2}|7(?:[0-3]\\d|4[0-8])))))" 

-?装置负数可选-

演示代码:

String str = "-?(\\d{1,5}|1\\d{5}|2(?:0\\d{4}|1(?:[0-3]\\d{3}|4(?:[0-6]\\d{2}|7(?:[0-3]\\d|4[0-8])))))"; 

System.out.println("214748".matches(str)); // true 
System.out.println("214746".matches(str)); // true 
System.out.println("2148".matches(str)); // true 
System.out.println("-21448".matches(str)); // true 
System.out.println("-214747".matches(str)); // true 
System.out.println("214749".matches(str)); // false 

正则表达式使用了以下的事实。对于范围[-214748, 214748]

  • 任何5个或更少位数字是有效的 - \\d{1,5}
  • 不限6开始与1位数是有效的 - 1\\d{5}
  • 用于开始2一个号码:
    • 另外5开始0位数字是有效的 - 20\\d{4}
    • 如果旁边的数字21
      1. 任何进一步的4个开始以[0-3]号码是有效的 - 21[0-3]\\d{3}
      2. 为了启动与4任何进一步的4位数字: 开始[0-6]
        • 号码是有效的 - 214[0-6]\d{2}
        • 如果4后位是7,然后
          1. [0-3]开头的任何其他号码均有效 - 2147[0-3]\\d
          2. 如果后位74,然后范围[0-8]4后是有效的 - 21474[0-8]
+1

@Downvoter关注意见。 –

+1

@NullUserException。我没有回答提供解决方案。我刚刚添加了为什么不应该使用正则表达式,并且给出了一个应该使用什么的概念。我希望OP至少能够和运营商一起完成这项工作。 –

+1

够公平的。但是在忍者编辑之前我就低估了答案 – NullUserException

1

这里有一个工作正则表达式,做你问什么:

^-?((([0-9]{1,5}|1[0-9]{5}|2(0[0-9]{4}|1([0-3][0-9]{3}|4([0-6][0-9]{2}|7([0-3][0-9]|4[0-7])))))([.][0-9]{2})?)|214748([.]00)?)$ 

这在很大程度上依赖于下面的子正则表达式,它从0到214747的范围相匹配:

([0-9]{1,5}|1[0-9]{5}|2(0[0-9]{4}|1([0-3][0-9]{3}|4([0-6][0-9]{2}|7([0-3][0-9]|4[0-7]))))) 

为什么从0至214747,而不是0到214748?因为这样做,避免匹配214748.01至214748.99(+/-)的值将更容易。打破正则表达式,我们得到:

^ # match start of line 
-? # optional minus sign 
    (# match one of the following groups, this one: 
    (
    ([0-9]{1,5}|1[0-9]{5}|2(0[0-9]{4}|1([0-3][0-9]{3}|4([0-6][0-9]{2}|7([0-3][0-9]|4[0-7]))))) 
    # the sub-regex above matches the range from 0 to 214747 
    ([.][0-9]{2})? # this matches the optional two decimals 
    ) 

    | # or this one: 
    214748([.]00)? # 214748, with optional zeroes 
) 
$ # match end of line 

有你有它,一个过于复杂的正则表达式,这是一个噩梦来看待,更不用说维护了。如果您需要更改范围,则需要大量工作。

我希望这个畸形鼓励该任务的使用正则表达式。像其他人所说的那样使用适当的工具进行处理。如果正则表达式为要求,告诉他们这是一个可怕的想法,并要求他们修复要求。