You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP如何将数字转换为印度计数体系的英文单词拼写

印度计数体系数字英文拼写转换方案

原生扩展限制说明

PHP自带的NumberFormatter扩展使用en_IN区域配置时,默认拼写规则仍会使用million单位,不支持直接切换为印度计数体系的lakhs表述,无法仅通过修改原有代码的参数实现需求。以下是两种可行实现方案:


方案1:快速字符串替换(适合简单场景)

如果你的业务场景仅需要处理常用的数值范围,可以在原生扩展输出的基础上做单位替换,代码如下:

$number = '1180590';

$locale = 'en_IN';
$fmt = numfmt_create($locale, NumberFormatter::SPELLOUT);
$in_words = numfmt_format($fmt, $number);

// 单位映射替换,自动适配大小写与数值换算
$replaceMap = [
    '/One Million/i' => 'Ten lakhs',
    '/(\d+) Million/i' => function($matches) {
        return ($matches[1] * 10) . ' lakhs';
    }
];
$in_words = preg_replace_callback(array_keys($replaceMap), array_values($replaceMap), $in_words);

echo $in_words;

方案说明

  • 适配100万以上的数值自动换算为对应的lakhs单位,例如2 Million会自动转换为20 lakhs
  • 实现成本低,适合不需要处理极特殊数值的业务场景

方案2:自定义转换逻辑(全场景适配)

如果需要完全适配印度计数体系的所有单位规则(包括crore、lakhs、thousand等层级),可以自行实现转换函数,完全规避原生扩展的规则限制,核心代码如下:

function numberToIndianWords($number) {
    $hyphen = ' ';
    $conjunction = ' ';
    $separator = ' ';
    $negative = 'negative ';
    $decimal = ' point ';
    $dictionary = [
        0                   => 'zero',
        1                   => 'one',
        2                   => 'two',
        3                   => 'three',
        4                   => 'four',
        5                   => 'five',
        6                   => 'six',
        7                   => 'seven',
        8                   => 'eight',
        9                   => 'nine',
        10                  => 'ten',
        11                  => 'eleven',
        12                  => 'twelve',
        13                  => 'thirteen',
        14                  => 'fourteen',
        15                  => 'fifteen',
        16                  => 'sixteen',
        17                  => 'seventeen',
        18                  => 'eighteen',
        19                  => 'nineteen',
        20                  => 'twenty',
        30                  => 'thirty',
        40                  => 'fourty',
        50                  => 'fifty',
        60                  => 'sixty',
        70                  => 'seventy',
        80                  => 'eighty',
        90                  => 'ninety',
        100                 => 'hundred',
        1000                => 'thousand',
        100000              => 'lakhs',
        10000000            => 'crore'
    ];

    if (!is_numeric($number)) {
        return false;
    }

    if ($number < 0) {
        return $negative . numberToIndianWords(abs($number));
    }

    $string = $fraction = null;

    if (strpos($number, '.') !== false) {
        list($number, $fraction) = explode('.', $number);
    }

    switch (true) {
        case $number < 21:
            $string = $dictionary[$number];
            break;
        case $number < 100:
            $tens   = ((int) ($number / 10)) * 10;
            $units  = $number % 10;
            $string = $dictionary[$tens];
            if ($units) {
                $string .= $hyphen . $dictionary[$units];
            }
            break;
        case $number < 1000:
            $hundred  = $number / 100;
            $remainder = $number % 100;
            $string = $dictionary[$hundred] . ' ' . $dictionary[100];
            if ($remainder) {
                $string .= $conjunction . numberToIndianWords($remainder);
            }
            break;
        case $number < 100000:
            $thousands = ((int)($number / 1000));
            $remainder = $number % 1000;
            $string = numberToIndianWords($thousands) . ' ' . $dictionary[1000];
            if ($remainder) {
                $string .= $separator . numberToIndianWords($remainder);
            }
            break;
        case $number < 10000000:
            $lakhs = ((int)($number / 100000));
            $remainder = $number % 100000;
            $string = numberToIndianWords($lakhs) . ' ' . $dictionary[100000];
            if ($remainder) {
                $string .= $separator . numberToIndianWords($remainder);
            }
            break;
        default:
            $crores = ((int)($number / 10000000));
            $remainder = $number % 10000000;
            $string = numberToIndianWords($crores) . ' ' . $dictionary[10000000];
            if ($remainder) {
                $string .= $separator . numberToIndianWords($remainder);
            }
            break;
    }

    if (null !== $fraction && is_numeric($fraction)) {
        $string .= $decimal;
        $words = [];
        foreach (str_split((string) $fraction) as $number) {
            $words[] = $dictionary[$number];
        }
        $string .= implode(' ', $words);
    }
    // 首字母大写适配需求
    return ucwords($string);
}

// 测试调用
echo numberToIndianWords(1180590);
// 输出:Ten Lakhs One Hundred Eighty Thousand Five Hundred Ninety

方案说明

  • 完全遵循印度计数体系的单位层级,不需要依赖intl扩展
  • 支持负数、小数的转换,适配所有常规数值场景

内容的提问来源于stack exchange,提问作者ChampionSemi SEO

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 03:36:03