如果我有这些字符串:
$string1 = "This book costs €25.99 in our shop."
在另一边
$string2 = "This book costs 25,99€ in our shop."
如何使用 preg_match 获得“€25.99”或“25,99€”?代码将如何?
请注意,有两种方式可以写入欧元符号。欧盟的正确方法是在25,99€之后写下符号并使用逗号作为desimal分离器即可。然而,很多美国人坚持使用美元方式(25.99欧元)和点数作为空间分隔符。
如何检查这两种情况并以最干净,最有效的方式获取带符号的值?
答案 0 :(得分:4)
这是原始正则表达式:€\d+(?:[,.]\d+)?|\d+(?:[,.]\d+)?€
preg_match ( "/€\d+(?:[,.]\d+)?|\d+(?:[,.]\d+)?€/" , $string1, $matches)
如果要考虑欧元和值之间的可选空格,请使用:
preg_match ( "/€ ?\d+(?:[,.]\d+)?|\d+(?:[,.]\d+)? ?€/" , $string1, $matches)
答案 1 :(得分:2)
agent-j 的模式在正确的轨道上,但我会做一些稍微限制的事情:
/€\d+(:?[.,]\d{2})?|\d+(:?[.,]\d{2})?€/
唯一的区别是小数部分限制为2个位置(如果存在)。我认为你不想允许像99,999€
这样的东西,特别是因为如果用美国风格写的话,这可能意味着“99000,999欧元”。
我认为你在提及最干净,最有效的方式时所想要的是,当你看到它时,上述模式似乎很笨拙和多余。它基本上是重复两次的\d+(:?[.,]\d{2})?
部分,其中符号切换边。这个感觉错了,但事实并非如此。如果不引入同样多的复杂性,你就无法真正解决它。即使你尝试用花哨的外观来解决它,它也会看起来像这样:
/^(?=.*€)€?\d+(:?[.,]\d{2})?((?<!€.*)€)?$/
显然不是一种改进。有时最明显的解决方案是最好的解决方案,即使它让你感觉很脏。
注意:如果你真的对它感到疯狂,你可以尝试一种变化(谨慎:未经测试,我在一段时间内没有做太多PHP):
$inner = "(:?\d{1,3}(?:([.,])\d{3})*(?:(?!\1)[.,]\d{2})?|\d*(?:[.,]\d{2})?)";
用法:
preg_match ( "/€" . $inner . "|" . $inner . "€/", $string1, $matches)
那也应该接受像99,999.99这样的东西; 999999,99; 9.999.999,99; 0.99;等
答案 2 :(得分:0)
检查两种情况:
/([$€]?[\d,]+[$€]?)/
?使[$€]
可选(字面意思为'0或1的......'),因此您必须检查退化情况,其中只有一个没有货币符号的裸号。