使用 preg_replace 重新格式化文本中的金额 PHP
Using preg_replace to reformat money amounts in text with PHP
我正在努力使用一些正则表达式。我想做的是在字符串中找到金额,删除 €、$ 或 £ 但保留数字,然后查看是否有 'b' 或 'm' - 其中案例分别写 'million platinum coins' 或 'million gold coin' 否则只写 'gold coins'.
我的大部分内容都是作为 hack(见下文)的小问题,我的正则表达式似乎不起作用。钱数不变。
期望的行为示例
我打算保留小数位和千位分隔符
1260万美元==>1260万金币
£2b ==> 200万铂金币
€99 ==> 99金币
我的代码
这是我的非工作代码(我怀疑我的正则表达式可能有误)。
protected function funnymoney($text){
$text = preg_replace('/[€$£]*([0-9\.,]+)([mb])/i','[=12=] %%',$text);
$text = str_replace('%b%','million platnum coins',$text);
$text = str_replace('%m%','million gold coins',$text);
$text = str_replace('%%','gold coins',$text);
return $text;
}
如果有人能向我解释我遗漏或错误的地方并指导我找到正确的答案,我将不胜感激。您可以放心地假设我对正则表达式知之甚少。如果可以的话,我想了解为什么该解决方案也有效。
你的正则表达式在字符串上有第一个完全匹配,它在返回数组的索引 0 上,但看起来你只需要捕获组。
$text = preg_replace('/[€$£]*([0-9\.,]+)([mb])/i',' %%',$text);
有趣的问题,顺便说一句!
这是你想要的吗?
<?php
/**
.6m ==> 12.6 million gold coins
£2b ==> 2 million platinum coins
€99 ==> 99 gold coins
*/
$str = <<<EOD
.6m
£2b
€99
EOD;
preg_match('/$(.*?)m/', $str, $string1);
echo $string1[1] . " million gold coins \n";
preg_match('/\£(.*?)b/', $str, $string2);
echo $string2[1] . " million platinum coins \n";
preg_match('/\€([0-9])/', $str, $string3);
echo $string3[1] . " gold coins \n";
// output:
// 12.6 million gold coins
// 2 million platinum coins
// 9 gold coins
使用 preg_replace_callback
,您可以在单个函数调用中执行此操作:
define ("re", '/[€$£]*(\.\d+|\d+(?:[.,]\d+)?)([mb]|)/i');
function funnymoney($text) {
return preg_replace_callback(re, function($m) {
return $m[1] .
($m[2] != "" ? " million" : "") . ($m[2] == "b" ? " platinum" : " gold") .
" coins";
}, $text);
}
// not call this function
echo funnymoney('.6m');
//=> "12.6 million gold coins"
echo funnymoney('£2b');
//=> "2 million platinum coins"
echo funnymoney('€99');
//=> "99 gold coins"
我不确定您打算如何处理小数位和千位分隔符,因此我的模式的这一部分可能需要调整。除此之外,匹配前导货币符号(使其为 consumed/removed,然后捕获数字子字符串,然后捕获可选的尾随单位(b
或 m
)。
使用查找数组将单位翻译成英语。当缺少单位字符时,应用查找数组中的回退值。
查找数组将使您的任务更易于阅读和维护。
代码:(Demo)
$str = '.1m
Foo
£2,2b
Bar
€99.9';
$lookup = [
'b' => 'million platinum coins',
'm' => 'million gold coins',
'' => 'gold coins',
];
echo preg_replace_callback(
'~[$£€](\d+(?:[.,]\d+)?)([bm]?)~iu',
function($m) use ($lookup) {
return "$m[1] " . $lookup[strtolower($m[2])];
},
$str
);
输出:
1.1 million gold coins
Foo
2,2 million platinum coins
Bar
99.9 gold coins
我正在努力使用一些正则表达式。我想做的是在字符串中找到金额,删除 €、$ 或 £ 但保留数字,然后查看是否有 'b' 或 'm' - 其中案例分别写 'million platinum coins' 或 'million gold coin' 否则只写 'gold coins'.
我的大部分内容都是作为 hack(见下文)的小问题,我的正则表达式似乎不起作用。钱数不变。
期望的行为示例
我打算保留小数位和千位分隔符
1260万美元==>1260万金币
£2b ==> 200万铂金币
€99 ==> 99金币
我的代码
这是我的非工作代码(我怀疑我的正则表达式可能有误)。
protected function funnymoney($text){
$text = preg_replace('/[€$£]*([0-9\.,]+)([mb])/i','[=12=] %%',$text);
$text = str_replace('%b%','million platnum coins',$text);
$text = str_replace('%m%','million gold coins',$text);
$text = str_replace('%%','gold coins',$text);
return $text;
}
如果有人能向我解释我遗漏或错误的地方并指导我找到正确的答案,我将不胜感激。您可以放心地假设我对正则表达式知之甚少。如果可以的话,我想了解为什么该解决方案也有效。
你的正则表达式在字符串上有第一个完全匹配,它在返回数组的索引 0 上,但看起来你只需要捕获组。
$text = preg_replace('/[€$£]*([0-9\.,]+)([mb])/i',' %%',$text);
有趣的问题,顺便说一句!
这是你想要的吗?
<?php
/**
.6m ==> 12.6 million gold coins
£2b ==> 2 million platinum coins
€99 ==> 99 gold coins
*/
$str = <<<EOD
.6m
£2b
€99
EOD;
preg_match('/$(.*?)m/', $str, $string1);
echo $string1[1] . " million gold coins \n";
preg_match('/\£(.*?)b/', $str, $string2);
echo $string2[1] . " million platinum coins \n";
preg_match('/\€([0-9])/', $str, $string3);
echo $string3[1] . " gold coins \n";
// output:
// 12.6 million gold coins
// 2 million platinum coins
// 9 gold coins
使用 preg_replace_callback
,您可以在单个函数调用中执行此操作:
define ("re", '/[€$£]*(\.\d+|\d+(?:[.,]\d+)?)([mb]|)/i');
function funnymoney($text) {
return preg_replace_callback(re, function($m) {
return $m[1] .
($m[2] != "" ? " million" : "") . ($m[2] == "b" ? " platinum" : " gold") .
" coins";
}, $text);
}
// not call this function
echo funnymoney('.6m');
//=> "12.6 million gold coins"
echo funnymoney('£2b');
//=> "2 million platinum coins"
echo funnymoney('€99');
//=> "99 gold coins"
我不确定您打算如何处理小数位和千位分隔符,因此我的模式的这一部分可能需要调整。除此之外,匹配前导货币符号(使其为 consumed/removed,然后捕获数字子字符串,然后捕获可选的尾随单位(b
或 m
)。
使用查找数组将单位翻译成英语。当缺少单位字符时,应用查找数组中的回退值。
查找数组将使您的任务更易于阅读和维护。
代码:(Demo)
$str = '.1m
Foo
£2,2b
Bar
€99.9';
$lookup = [
'b' => 'million platinum coins',
'm' => 'million gold coins',
'' => 'gold coins',
];
echo preg_replace_callback(
'~[$£€](\d+(?:[.,]\d+)?)([bm]?)~iu',
function($m) use ($lookup) {
return "$m[1] " . $lookup[strtolower($m[2])];
},
$str
);
输出:
1.1 million gold coins
Foo
2,2 million platinum coins
Bar
99.9 gold coins