我需要一个正则表达式来获取可以是数字的值
111.111,11
111,111.11
111,111
将整数部分和小数部分分开,以便我可以使用正确的语法将其存储到数据库中。
我尝试过 ([0-9]{1,3}[,.]?)+([,.][0-9]{2})?
,但没有成功,因为它无法检测出第二部分 :(
结果应该看起来像:
111.111,11 -> $1 = 111111; $2 = 11
我需要一个正则表达式来获取可以是数字的值
111.111,11
111,111.11
111,111
将整数部分和小数部分分开,以便我可以使用正确的语法将其存储到数据库中。
我尝试过 ([0-9]{1,3}[,.]?)+([,.][0-9]{2})?
,但没有成功,因为它无法检测出第二部分 :(
结果应该看起来像:
111.111,11 -> $1 = 111111; $2 = 11
第一个回答:
这个匹配模式是 #,###,##0.00
。
^[+-]?[0-9]{1,3}(?:\,?[0-9]{3})*(?:\.[0-9]{2})?$
这与 #.###.##0,00
相匹配:
^[+-]?[0-9]{1,3}(?:\.?[0-9]{3})*(?:\,[0-9]{2})?$
将两者合并(有更聪明/更短的方法来编写它,但它可以工作):
(?:^[+-]?[0-9]{1,3}(?:\,?[0-9]{3})*(?:\.[0-9]{2})?$)
|(?:^[+-]?[0-9]{1,3}(?:\.?[0-9]{3})*(?:\,[0-9]{2})?$)
你也可以在最后一个逗号(或句号)处添加一个捕获组,以检查使用了哪个符号。
第二个答案:
正如 Alan M 指出的那样,我的先前解决方案可能无法拒绝像 11,111111.00
这样的值,其中一个逗号缺失,但另一个不缺失。经过一些测试,我得出了以下正则表达式,可以避免这个问题:
^[+-]?[0-9]{1,3}
(?:(?<comma>\,?)[0-9]{3})?
(?:\k<comma>[0-9]{3})*
(?:\.[0-9]{2})?$
这需要一些解释:
^[+-]?[0-9]{1,3}
匹配前面的(1到3位)数字;
(?:(?<comma>\,?)[0-9]{3})?
匹配一个可选的逗号后跟更多的3位数字,并在一个名为“comma”的组中捕获逗号(或不存在逗号);
(?:\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})?
)$
这个变量捕获了所使用的分隔符:
^[+-]?[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})?
)$
编辑1: “cents”现在是可选的;
编辑2: 添加了文本;
编辑3: 添加了第二个解决方案;
编辑4: 添加了完整解决方案;
编辑5: 添加标题;
编辑6: 添加捕获;
编辑7: 最后一个答案分成两个版本;(?:\.?[0-9]{3})*
应该是 (?:\.[0-9]{3})*
。否则,你可能会匹配到像 11,111111.00
或者 1111.111,00
这样的东西。 - Alan Moore,
或'.'
)字符。后来我意识到您想要捕获数字本身。我不确定使用原始正则表达式是否可能。您可以使用我编写的正则表达式验证字符串并捕获分隔符。然后,在第二步中,您可以拆分数字并删除分隔符。 - jpbochi首先使用该正则表达式来确定逗号或点号作为逗号分隔符的使用情况(它获取最后两个中的一个):
[0-9,\.]*([,\.])[0-9]*
我将剥离所有其他与之前不匹配的符号。如果没有匹配项,则已经有一个整数,可以跳过下一步。所选符号的删除可以很容易地使用正则表达式完成,但也有许多其他函数可以更快/更好地完成此操作。
然后您将得到一个以整数形式表示的数字,可能后跟逗号或点和小数部分,其中整数部分和小数部分可以轻松地用以下正则表达式分开。
([0-9]+)[,\.]?([0-9]*)
祝你好运!
编辑:
这里有一个用Python编写的示例,我认为代码应该是自解释的,如果不是,请随时询问。
import re
input = str(raw_input())
delimiterRegex = re.compile('[0-9,\.]*([,\.])[0-9]*')
splitRegex = re.compile('([0-9]+)[,\.]?([0-9]*)')
delimiter = re.findall(delimiterRegex, input)
if (delimiter[0] == ','):
input = re.sub('[\.]*','', input)
elif (delimiter[0] == '.'):
input = re.sub('[,]*','', input)
print input
111.111,11
111111.11
111,111.11
111111.11
111,111
111,111
111,111
中的逗号是千位分隔符(TS)。如果有小数分隔符(DS),则必须后跟正好两个数字(他在问题下的评论中澄清了这一点)。因此,您的第一个正则表达式必须以 ([,.][0-9]{2})?
结束,就像 OP 的那样。但他还试图验证 TS 是否正确分布。 - Alan Moore怎么样
/(\d{1,3}(?:,\d{3})*)(\.\d{2})?/
/(\d[\d,]*)(\.\d{2})?/
如果你不这样做。
$value = "111,111.11";
$value =~ s/\.//g;
$value =~ m/(\d+)(?:,(\d+))?/;
$1 = 带有去除小数点的前导整数 $2 = 如果存在,则为undef,否则为逗号后面的数字。