正则表达式解析国际浮点数

LuR*_*RsT 6 regex internationalization

我需要一个正则表达式来获取可以的数值

111.111,11

111,111.11

111,111
Run Code Online (Sandbox Code Playgroud)

并分隔整数和小数部分,以便我可以使用正确的语法存储在DB中

我尝试([0-9]{1,3}[,.]?)+([,.][0-9]{2})?没有成功,因为它没有检测到第二部分:(

结果应如下所示:

111.111,11 -> $1 = 111111; $2 = 11
Run Code Online (Sandbox Code Playgroud)

jpb*_*chi 9

第一个答案:

匹配#,###,##0.00:

^[+-]?[0-9]{1,3}(?:\,?[0-9]{3})*(?:\.[0-9]{2})?$
Run Code Online (Sandbox Code Playgroud)

这匹配#.###.##0,00:

^[+-]?[0-9]{1,3}(?:\.?[0-9]{3})*(?:\,[0-9]{2})?$
Run Code Online (Sandbox Code Playgroud)

加入这两个(有更聪明/更短的方式来编写它,但它的工作原理):

(?:^[+-]?[0-9]{1,3}(?:\,?[0-9]{3})*(?:\.[0-9]{2})?$)
|(?:^[+-]?[0-9]{1,3}(?:\.?[0-9]{3})*(?:\,[0-9]{2})?$)
Run Code Online (Sandbox Code Playgroud)

您还可以将捕获组添加到最后一个逗号(或点)以检查使用了哪个.


第二个答案:

正如Alan M指出的那样,我以前的解决方案可能无法拒绝像11,111111.00逗号丢失的值,但另一个不是.经过一些测试后,我达到了以下正则表达式,避免了这个问题:

^[+-]?[0-9]{1,3}
(?:(?<comma>\,?)[0-9]{3})?
(?:\k<comma>[0-9]{3})*
(?:\.[0-9]{2})?$
Run Code Online (Sandbox Code Playgroud)

这值得一些解释:

  • ^[+-]?[0-9]{1,3} 匹配第一个(1到3)数字;

  • (?:(?<comma>\,?)[0-9]{3})? 匹配可选逗号后跟3个数字,并在名为'逗号'的组中捕获逗号(或不存在的逗号);

  • (?:\k<comma>[0-9]{3})* 匹配之前使用的逗号的零到任何重复(如果有的话),后跟3位数字;

  • (?:\.[0-9]{2})?$ 匹配字符串末尾的可选"美分".

当然,这只会覆盖#,###,##0.00(而不是#.###.##0,00),但你可以像我上面那样加入正则表达式.


最终答案:

现在,一个完整的解决方案 缩进和换行只是为了便于阅读.

^[+-]?[0-9]{1,3}
(?:
    (?:\,[0-9]{3})*
    (?:.[0-9]{2})?
|
    (?:\.[0-9]{3})*
    (?:\,[0-9]{2})?
|
    [0-9]*
    (?:[\.\,][0-9]{2})?
)$
Run Code Online (Sandbox Code Playgroud)

此变体捕获使用的分隔符:

^[+-]?[0-9]{1,3}
(?:
    (?:(?<thousand>\,)[0-9]{3})*
    (?:(?<decimal>\.)[0-9]{2})?
|
    (?:(?<thousand>\.)[0-9]{3})*
    (?:(?<decimal>\,)[0-9]{2})?
|
    [0-9]*
    (?:(?<decimal>[\.\,])[0-9]{2})?
)$
Run Code Online (Sandbox Code Playgroud)

编辑1:"美分"现在是可选的; 编辑2:添加文字; 编辑3:添加第二个解决方案; 编辑4:添加完整的解决方案; 编辑5:添加标题; 编辑6:捕获添加; 编辑7:最后的答案分为两个版本;