如何使用PHP将包含HTML分数的字符串转换为小数格式字符串
PHP 俗分数转小数实现方案
实现思路
- 基于你提供的分数映射表,将所有分数符号拼接为正则匹配集合,增加
u修饰符兼容Unicode字符匹配 - 正则同时覆盖两种匹配场景:单独的分数符号、整数+可选空格+分数符号的带分数格式
- 使用
preg_replace_callback对匹配结果做动态计算:存在整数部分就叠加整数和分数的小数值,没有则直接使用分数的小数值,最后格式化小数位数匹配预期输出
完整可运行代码
<?php $mappingArr = [ '½' => 1/2, '⅓' => 1/3, '⅔' => 2/3, '¼' => 1/4, '¾' => 3/4, '⅕' => 1/5, '⅖' => 2/5, '⅗' => 3/5, '⅘' => 4/5, '⅙' => 1/6, '⅚' => 5/6, '⅐' => 1/7, '⅛' => 1/8, '⅜' => 3/8, '⅝' => 5/8, '⅞' => 7/8, '⅑' => 1/9, '⅒' => 1/10 ]; /** * 将字符串中的俗分数转换为小数格式 * @param string $input 待处理字符串 * @param array $mapping 分数映射表 * @return string 处理后的字符串 */ function convertFractionToDecimal(string $input, array $mapping): string { // 拼接正则匹配的分数集合,加preg_quote避免正则特殊字符问题 $fractionChars = implode('|', array_map(function($char) { return preg_quote($char, '/'); }, array_keys($mapping))); // 匹配规则:可选的整数部分 + 可选的空格 + 分数符号,加u修饰符兼容Unicode $pattern = "/(\d+)?\s?($fractionChars)/u"; return preg_replace_callback($pattern, function($matches) use ($mapping) { $integer = empty($matches[1]) ? 0 : (int)$matches[1]; $fractionVal = $mapping[$matches[2]]; $total = $integer + $fractionVal; // 格式化小数,去掉末尾无意义的0和多余的小数点 return rtrim(rtrim(number_format($total, 2), '0'), '.'); }, $input); } // 测试用例 $fractionString1 = "⅓ Test something else"; $fractionString2 = "1½ Test (test)"; $fractionString3 = "1 ⅔ Test, test"; // 输出结果和预期完全一致 echo convertFractionToDecimal($fractionString1, $mappingArr).PHP_EOL; // 0.33 Test something else echo convertFractionToDecimal($fractionString2, $mappingArr).PHP_EOL; // 1.5 Test (test) echo convertFractionToDecimal($fractionString3, $mappingArr).PHP_EOL; // 1.67 Test, test ?>
注意事项
- 必须给正则加
u修饰符,否则无法正确识别Unicode编码的俗分数字符 - 如果需要调整小数保留位数,直接修改
number_format的第二个参数即可 - 后续新增分数映射直接在
$mappingArr里添加即可,不需要修改转换逻辑
内容的提问来源于stack exchange,提问作者Tim
相关产品推荐
相关产品推荐

