[英]How can I change NumberFormatter::parseCurrency() behavior of accepting white space and non breaking space?
我正在尝试将本地化的货币字符串解析为货币和浮动值。
一切都运作良好,现在我们遇到了一些问题。 看起来NumberFormatter :: parseCurrency使用了一个额外的不可见字符:
Testcode:
<?php
$formatter = new NumberFormatter("de_DE", NumberFormatter::CURRENCY);
var_dump(array(
$formatter->parseCurrency("88,22 €", $curr), // taken from output of $formatter->format(88.22)
$formatter->parseCurrency("88,22 €", $curr), // input with keyboard
$formatter->parseCurrency("88,22 \xE2\x82\xAc", $curr), // just a test
$formatter->format(88.22),
"88,22 €" // keyboard input
));
输出:
array(5) {
[0]=> float(88,22)
[1]=> bool(false)
[2]=> bool(false)
[3]=> string(10) "88,22 €" // this as input works
[4]=> string(9) "88,22 €" // this not...
}
如您所见,输出3和4的字符串长度存在差异。
我在PHP 5.3(启用了mbstring的ubuntu)和5.4(Mac OS X上的Zend Server)中得到了相同的结果。
主要问题是,来自我的表单(ZF1应用程序)的输入值与索引4的输出相同...
有什么建议? 提前致谢
EDIT1:
工作价值的hexdump:
00000000 38 38 2c 32 32 c2 a0 e2 82 ac 0a |88,22......|
0000000b
非工作价值的hexdump:
00000000 38 38 2c 32 32 20 e2 82 ac 0a |88,22 ....|
0000000a
EDIT2:
使用的whitepsace似乎是一个问题。 c2 a0是NO-BREAK SPACE,并且(可能?)是NumberFormatter :: parseCurrency()所必需的。 但0x20是默认空格(在输入表单中输入)。 当前的解决方法是使用$value = str_replace("\\x20", "\\xC2\\xA0", $value);
将NO-BREAK SPACE替换为空格$value = str_replace("\\x20", "\\xC2\\xA0", $value);
EDIT3:
在另一个系统(带有Zend Server 5.6的Mac OS X,启用了mbstring,PHP 5.3.14)中,一切都按预期工作:
array(5) {
[0]=> float(88,22)
[1]=> float(88,22)
[2]=> float(88,22)
[3]=> string(9) "88,22 €"
[4]=> string(9) "88,22 €"
}
Edit4:
使用空间和使用非中断空间配置之间的主要区别是ICU版本:
工作版:
intl
Internationalization support => enabled
version => 1.1.0
ICU version => 3.8.1
Directive => Local Value => Master Value
intl.default_locale => no value => no value
intl.error_level => 0 => 0
不工作版本:
intl
Internationalization support => enabled
version => 1.1.0
ICU version => 4.8.1.1
ICU Data version => 4.8.1
Directive => Local Value => Master Value
intl.default_locale => no value => no value
intl.error_level => 0 => 0
NumberFormatter::parseCurrency
是ICU库函数unum_parseDoubleCurrency
一个瘦包装器( 参见source )。
ICU库函数是限制性的,因为它只解析由其双重函数unum_formatDoubleCurrency
引起的字符串。 格式由Unicode语言环境数据驱动,该数据指定货币值和数值之间的不间断空格。 显然,该库的早期版本接受了其他空白字符。
简而言之,您不能使NumberFormatter::parseCurrency
接受空格。 但是, Zend_Currency
默认情况下也应该输出不间断的空格:
$currency = new Zend_Currency(array(
'currency' => 'EUR',
'value' => 88.22,
), 'de_DE');
var_dump(
strval($currency), // 88,22 €
strpos($currency, "\x20"), // false
strpos($currency, "\xc2\xa0") // 5
);
问题是您的应用程序的哪一部分正在输出空格以及您如何解决它。 你提到它是表单的一部分,所以也许你可以看一下表单将货币和值作为单独的字段返回,这样你就不必担心解析数字了。 如果用户自己输入字符串“88,22€”,则可能会遇到更多问题,而不仅仅是空白问题。 话虽如此,你提到的解决方法(用\\x20
\\xc2\\xa0
替换\\x20
)是解决这个问题的唯一方法,如果你想使用NumberFormatter
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.