-1

您如何编写与货币数字范围 from-214748.00-214748to匹配的正则表达式214748.00

我试过这个但没有工作。

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

2 回答 2

5

不不不。您为这项工作使用了错误的工具。正则表达式只是一个文本处理工具。它不擅长解释文本的含义。当涉及到识别您需要处理的文本的语义时,这就是正则表达式不好的地方。

您应该使用简单的语言工具和运算符来完成这项工作。除此之外,如果您处理货币,请避免使用doubleor float。它们没有足够的精度来准确地表示所有浮点数。改用 a 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}
        • 如果后面的数字47,那么
          1. 任何其他以开头的数字[0-3]都是有效的 -2147[0-3]\\d
          2. 如果后面的数字74,那么[0-8]后面的范围4是有效的 -21474[0-8]
于 2013-10-03T16:46:39.367 回答
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

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

我希望这个怪物不鼓励使用正则表达式来完成这项任务。像其他人说的那样做,并使用适当的工具进行处理。如果需要正则表达式,请告诉他们这是一个可怕的想法并要求他们修复要求。

于 2013-10-03T17:18:30.610 回答