货币正则表达式 [英] Currency Regular Expression

查看:51
本文介绍了货币正则表达式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想我为我需要的东西创建了一个有效的正则表达式.只是想知道是否有人可以打破它或看到更短的编写方式.

正则表达式应验证以下内容...

  • 美元符号可选
  • 负数用括号表示,而不是减号
  • 如果为负数,美元符号应在括号外
  • 逗号是可选的
  • 最大数量为 999999.99
  • 最小号码是 (999999.99)
  • 不必提供小数,但如果提供,则不超过两个数字

这里有一些有效的例子......

99 美元0.99 美元(999,999.99 美元)(999999)($999999)(999,999)99,999.9

这是我想出来的:

^\$?(((\d{1,6}(\.\d{1,2})?)|(\d{1,3},\d{3}(\.\d{1,2})?)|\(((\d{1,6}(\.\d{1,2})?)|(\d{1,3},\d{3}(\.\d{1,2})?))\)))$

更正,我的规范是错误的,如果使用美元符号,它必须在括号内.

解决方案

您可以将一位到六位数字之间;最后三位数字前的逗号是可选的"更简洁地表达为 \d{1,3}(,?\d{3})?.这也允许您只包含 (\.\d{1,2})? 的两个副本:一个用于正数,一个用于负数,而不是一个没有逗号的正数,一个用于带逗号的正数等

此外,\d{1,2} 可以稍微缩短为 \d\d?,但我不确定这是否有所改进.>

所以,除非使用诸如 (?(1)) 之类的符号来测试是否设置了反向引用,这是我看到的最短版本:

^(\$?\d{1,3}(,?\d{3})?(\.\d\d?)?|\(\$?\d{1,3}(,?\d{3})?(\.\d\d?)?\))$

您的正则表达式可能不受欢迎的一个方面是它们将允许类似 $00,012.7 的内容,即使没有人以这种方式使用前导零.您可以通过要求第一个数字非零来解决这个问题,然后添加一个特殊情况来处理 $0(0.12) 等等:

^(\$?(0|[1-9]\d{0,2}(,?\d{3})?)(\.\d\d?)?|\(\$?(0|[1-9]\d{0,2}(,?\d{3})?)(\.\d\d?)?\))$

编辑添加:使用像 F.J 在他/她的回答中建议的前瞻断言,后者可以缩短为:

^(?!\(.*[^)]$|[^(].*\)$)\(?\$?(0|[1-9]\d{0,2}(,?\d{3})?)(\.\d\d?)?\)?$

I think I created a working regular expression for what I need. Just wondering if anyone can break it or see a shorter way to write it.

The regular expression should validate the following...

  • Dollar sign optional
  • Negative numbers signified with parenthesis, not a minus
  • If negative, dollar sign should be outside the parenthesis
  • Commas are optional
  • Max number is 999999.99
  • Min number is (999999.99)
  • Decimals do not have to be supplied, but if so, no more than two digits

So here are some examples of valid ones...

9
$9
$0.99
($999,999.99)
(999999)
($999999)
(999,999)
99,999.9

This is what I have come up with:

^\$?(((\d{1,6}(\.\d{1,2})?)|(\d{1,3},\d{3}(\.\d{1,2})?)|\(((\d{1,6}(\.\d{1,2})?)|(\d{1,3},\d{3}(\.\d{1,2})?))\)))$

CORRECTION, my spec was wrong, if the dollar sign is used it must be INSIDE the parenthesis.

解决方案

You can express "between one and six digits; comma before the last three digits is optional" a bit more tersely as \d{1,3}(,?\d{3})?. This also allows you to include only two copies of (\.\d{1,2})?: one for positive and one for negative, instead of one for positive-without-comma, one for positive-with-comma, etc.

Also, \d{1,2} can be shortened slightly to \d\d?, though I'm not sure if that's an improvement.

So, barring some notation like (?(1)) to test if a backreference is set, here's the shortest version I see:

^(\$?\d{1,3}(,?\d{3})?(\.\d\d?)?|\(\$?\d{1,3}(,?\d{3})?(\.\d\d?)?\))$

One perhaps-undesirable aspect of your regex, and of this one, is that they will allow something like $00,012.7, even though no one uses leading zeroes that way. You can address that by requiring the first digit to be nonzero, and then adding a special case to handle $0 and (0.12) and so on:

^(\$?(0|[1-9]\d{0,2}(,?\d{3})?)(\.\d\d?)?|\(\$?(0|[1-9]\d{0,2}(,?\d{3})?)(\.\d\d?)?\))$

Edited to add: using a lookahead assertion like F.J suggests in his/her answer, the latter can be shortened to:

^(?!\(.*[^)]$|[^(].*\)$)\(?\$?(0|[1-9]\d{0,2}(,?\d{3})?)(\.\d\d?)?\)?$

这篇关于货币正则表达式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆