您能否建议一个支持美国和欧洲数字格式的正则表达式
例如:US - 999,999.99 英国 - 999.999,99
答案 0 :(得分:0)
一个简单的解决方案是匹配一个或另一个:
(?:\d{1,3})(?:\.\d{3})?(?:\.\d{3})?(?:,\d+)?|(?:\d{1,3})(?:,\d{3})?(?:,\d{3})?(?:\.\d+)?
匹配1-3位数字,可选地后跟完整停止和三位数字,可选地后跟全停和三位数字,可选地后跟一个逗号和任意数量的数字(根据您的示例,您可能希望限制为两位) 。然后,如果这不匹配,请尝试完全停止并以逗号反转。
编辑: 考虑到你在kbysiec的回答中的评论,你可能想检查开始和结束 -
(?:\s|^)(?:(?:\d{1,3})(?:\.\d{3})?(?:\.\d{3})?(?:,\d+)?|(?:\d{1,3})(?:,\d{3})?(?:,\d{3})?(?:\.\d+)?)(?:\s|$)
这可以确保数字前面有空格或行的开头,并以空格或行尾结束。
此致
编辑2:
(?:\s|^)(?:(?:\d{1,3})(?:\.\d{3})*(?:,\d+)?|(?:\d{1,3})(?:,\d{3})*(?:\.\d+)?)(?:\s|$)
缩短并允许数字为任意长度。
答案 1 :(得分:0)
(?<=\s|^)(?:\d{1,3}(?:,\d{3})*(?:\.\d+)?|\d{1,3}(?:.\d{3})*(?:\,\d+)?)(?=\s|$)
应该正确匹配所有内容,同时检查点/逗号的错误展示位置,如here
在最后一个前瞻之前投掷|\d*([,.]\d+)?
以匹配非分开的数字。
这个想法是你会有,xxx.yy
,在这种情况下,有一个长度为1-3的数字。这种情况可以重演。
尽管如此,这对于正则表达式来说并不是一件容易的事,而且这个正则表达式不是很易读。其他一些工具可能会更好。
答案 2 :(得分:0)
首先,每当有人要求正则表达式时,我的第一反应就是询问这是否适合这项工作:https://softwareengineering.stackexchange.com/q/223634/98845
有些语言提供了获取货币价值的方法。这个答案将使用C ++的:get_money
这样的输入:
Jonathan Mee $ 1,234.56 987654321 true
可以在流:get_money
中使用cin >> a >> b >> get_money(c) >> d >> e;
来分配值:
string a
:"Jonathan"
string b
:"Mee"
long double c
:123456
int d
:987654321
bool e
:true
get_money
的处理方式基于流locale
,特别是locale
的{{3}}。可能已经有locale
的编译器/操作系统支持已经以这种方式处理资金:moneypunct
如果没有内置支持,请不要担心。 locale
的方面是支持广泛自定义的C ++功能,要解决此问题,只需要覆盖https://msdn.microsoft.com/en-us/goglobal/bb896001.aspx和do_decimal_point
。这里有一个关于如何执行此操作的详尽说明:do_thousands_sep
但是就本答案而言,该答案的punct_facet
将被批评为ganked:
template <typename T>
class punct_facet : public T {
private:
void Init(const T* money){
const auto vTablePtrSize = sizeof(void*);
memcpy(reinterpret_cast<char*>(this) + vTablePtrSize, reinterpret_cast<const char*>(money) + vTablePtrSize, sizeof(T) - vTablePtrSize);
}
protected:
typename T::char_type do_decimal_point() const {
return typename T::char_type(',');
}
typename T::char_type do_thousands_sep() const {
return typename T::char_type('.');
}
public:
punct_facet(){
Init(&use_facet<T>(cout.getloc()));
}
punct_facet(const T* money){
Init(money);
}
};
这样的实现允许像这样使用https://stackoverflow.com/a/31390558/2642059:
locale foo("en-US");
cin.imdue(locale(foo, new punct_facet<moneypunct<char>>(&use_facet<moneypunct<char>>(foo))));
这意味着输入如下:
Jonathan Mee $ 1.234,56 987654321 true
可以使用原始命令cin >> a >> b >> get_money(c) >> d >> e;
读取,以分配值:
string a
:"Jonathan"
string b
:"Mee"
long double c
:123456
int d
:987654321
bool e
:true
即使是未经训练的人也可以看到punct_facet
类比一次设置和使用正则表达式所需的代码更多。 C ++的moneypunct
在代码中优于regex,其中多次使用它的方式无法封装到单个regex函数中。与正则表达式相比,moneypunct
也提供了明显的优势:
locale
facet constructor兼容get_money
会使用比正则表达式更专业的代码