在 PHP 中将数字 (1, 2, 3) 转换为字符串 (一, 二, 三)

发布于 2024-08-18 08:06:41 字数 94 浏览 2 评论 0 原文

有谁知道如何在 PHP 中将 1、2 或 3 等数字转换为文本版本(一、二、三)?我只需要从 1 转换到 99。我知道我可以编写一个巨大的 switch 语句,但这太荒谬了。

Does anyone know how to convert a number such as 1, 2, or 3 to their text version (one, two, three) in PHP? I only need to convert from 1 to 99. I know I could write a huge switch statement but that would be ridiculous.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

不必你懂 2024-08-25 08:06:42

有一个 PEAR 包可以做到这一点。它的编号确实比 99 高,并且是多语言的,因此它可能比您需要的更重量级,但仍然值得一看:

http://pear.php.net/package/Numbers_Words

There's a PEAR package that does this. It does number WAY higher than 99 and is multi-language, so it might be more heavyweight than you need, but still worth checking out:

http://pear.php.net/package/Numbers_Words

合久必婚 2024-08-25 08:06:42

我最终不得不在面试过程中为编码测试编写此内容。你可以在 Github 上看到我的最终代码:https://github.com/mangs/integers2words

为了方便起见,这里是实现 int2str() 功能的 DemoLibrary 类(所有类成员仅支持 int2str() 功能):

<?php

/**
 * Demo library class intended to be added to in the future
 */
class DemoLibrary {
    /***** NOTE: a const cannot be an array in PHP, so making these arrays static is the next best thing *****/

    /**
     * @var array $_numbersUnder20 Array containing the word associated with the index's number value
     */
    private static $_numbersUnder20 = [
        'zero', 'one', 'two', 'three', 'four',
        'five', 'six', 'seven', 'eight', 'nine',
        'ten', 'eleven', 'twelve', 'thirteen', 'fourteen',
        'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen'
    ];

    /**
     * @var array $_tensDigits Array containing all tens digit values except 10
     */
    private static $_tensDigits = [
        'twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety'
    ];

    /**
     * @var array $_orderOfMagnitude Array containing the higher-order digit values; can also be
     *                               thought of as the order of magnitude of the target digit
     */
    private static $_orderOfMagnitude = [
        // Stopped at "quintillion" because the maximum PHP int value on 64-bit Linux is
        // 9,223,372,036,854,775,807 (a.k.a. 2^63 - 1 because PHP doesn't support unsigned ints)
        'thousand', 'million', 'billion', 'trillion', 'quadrillion', 'quintillion'
    ];


    /**
     * Recursively calculates the string-, word-based equivalent of the target integer
     *
     * @param integer $num Integer whose value will be converted to a word-based string
     * @param boolean $recursive Determines if the currently-executing code is being called
     *                           recursively; allows for non-recursive 0 to be converted to "zero"
     *                           otherwise use an empty string
     *
     * @throws InvalidArgumentException if the first argument is not of type int
     *
     * @return string Partially- or fully-built word-based representation of the target integer
     */
    private function _integerToWords($num, $recursive=false) {
        // Ensure a valid integer
        if(!is_int($num)) {
            throw new InvalidArgumentException(
                __FUNCTION__ . ' expects parameter 1 to be of type integer; actual type: ' .
                gettype($num)
            );
        }


        /***** Perform the int to string conversion based on the size of $num *****/

        // Negative
        if($num < 0) {
            return 'negative ' . $this->_integerToWords(-1 * $num, true);
        }

        // 0 or no value in the lowest digits
        if($num === 0) {
            return $recursive ? '' : 'zero';
        }

        // 1-19
        if($num < 20) {
            return self::$_numbersUnder20[$num];
        }

        // 20 - 99
        if($num < 100) {
            $highDigitValue = intval(floor($num / 10) - 2); // Value of the highest-order digit
            $remainingValue = $num % 10; // Value of the remaining digits
            return
                self::$_tensDigits[$highDigitValue] .
                '-' .
                $this->_integerToWords($remainingValue, true);
        }

        // 100 - 999
        if($num < 1000) {
            $highDigitValue = intval(floor($num / 100)); // Value of the highest-order digit
            $remainingValue = $num % 100; // Value of the remaining digits
            return
                $this->_integerToWords($highDigitValue, true) .
                '-hundred ' .
                $this->_integerToWords($remainingValue, true);
        }

        // 1,000+
        $quotient = $num;
        $divideCount = 0;
        while($quotient >= 1000) {
            $quotient /= 1000;
            ++$divideCount;
        }
        $highDigitValue = intval(floor($quotient)); // Value of the highest-order digit
        $remainingValue = $num - ($highDigitValue * pow(1000, $divideCount)); // Value of the remaining digits
        return
            $this->_integerToWords($highDigitValue, true) .
            '-' .
            self::$_orderOfMagnitude[$divideCount - 1] .
            ' ' .
            $this->_integerToWords($remainingValue, true);
    }


    /**
     * @api
     *
     * Calculates the string-, word-based equivalent of the target integer
     *
     * @param integer $num Integer whose value will be converted to a word-based string
     *
     * @return string Fully-built word-based representation of the target integer
     */
    public function int2str($num) {
        return trim($this->_integerToWords($num), "- \t\n\r\0\x0B");
    }
}

I ended up having to write this for a coding test during an interview process. You can see my final code at Github here: https://github.com/mangs/integers2words

For convenience, here is the DemoLibrary class that implements this int2str() functionality (all class members are there only to support the int2str() functionality):

<?php

/**
 * Demo library class intended to be added to in the future
 */
class DemoLibrary {
    /***** NOTE: a const cannot be an array in PHP, so making these arrays static is the next best thing *****/

    /**
     * @var array $_numbersUnder20 Array containing the word associated with the index's number value
     */
    private static $_numbersUnder20 = [
        'zero', 'one', 'two', 'three', 'four',
        'five', 'six', 'seven', 'eight', 'nine',
        'ten', 'eleven', 'twelve', 'thirteen', 'fourteen',
        'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen'
    ];

    /**
     * @var array $_tensDigits Array containing all tens digit values except 10
     */
    private static $_tensDigits = [
        'twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety'
    ];

    /**
     * @var array $_orderOfMagnitude Array containing the higher-order digit values; can also be
     *                               thought of as the order of magnitude of the target digit
     */
    private static $_orderOfMagnitude = [
        // Stopped at "quintillion" because the maximum PHP int value on 64-bit Linux is
        // 9,223,372,036,854,775,807 (a.k.a. 2^63 - 1 because PHP doesn't support unsigned ints)
        'thousand', 'million', 'billion', 'trillion', 'quadrillion', 'quintillion'
    ];


    /**
     * Recursively calculates the string-, word-based equivalent of the target integer
     *
     * @param integer $num Integer whose value will be converted to a word-based string
     * @param boolean $recursive Determines if the currently-executing code is being called
     *                           recursively; allows for non-recursive 0 to be converted to "zero"
     *                           otherwise use an empty string
     *
     * @throws InvalidArgumentException if the first argument is not of type int
     *
     * @return string Partially- or fully-built word-based representation of the target integer
     */
    private function _integerToWords($num, $recursive=false) {
        // Ensure a valid integer
        if(!is_int($num)) {
            throw new InvalidArgumentException(
                __FUNCTION__ . ' expects parameter 1 to be of type integer; actual type: ' .
                gettype($num)
            );
        }


        /***** Perform the int to string conversion based on the size of $num *****/

        // Negative
        if($num < 0) {
            return 'negative ' . $this->_integerToWords(-1 * $num, true);
        }

        // 0 or no value in the lowest digits
        if($num === 0) {
            return $recursive ? '' : 'zero';
        }

        // 1-19
        if($num < 20) {
            return self::$_numbersUnder20[$num];
        }

        // 20 - 99
        if($num < 100) {
            $highDigitValue = intval(floor($num / 10) - 2); // Value of the highest-order digit
            $remainingValue = $num % 10; // Value of the remaining digits
            return
                self::$_tensDigits[$highDigitValue] .
                '-' .
                $this->_integerToWords($remainingValue, true);
        }

        // 100 - 999
        if($num < 1000) {
            $highDigitValue = intval(floor($num / 100)); // Value of the highest-order digit
            $remainingValue = $num % 100; // Value of the remaining digits
            return
                $this->_integerToWords($highDigitValue, true) .
                '-hundred ' .
                $this->_integerToWords($remainingValue, true);
        }

        // 1,000+
        $quotient = $num;
        $divideCount = 0;
        while($quotient >= 1000) {
            $quotient /= 1000;
            ++$divideCount;
        }
        $highDigitValue = intval(floor($quotient)); // Value of the highest-order digit
        $remainingValue = $num - ($highDigitValue * pow(1000, $divideCount)); // Value of the remaining digits
        return
            $this->_integerToWords($highDigitValue, true) .
            '-' .
            self::$_orderOfMagnitude[$divideCount - 1] .
            ' ' .
            $this->_integerToWords($remainingValue, true);
    }


    /**
     * @api
     *
     * Calculates the string-, word-based equivalent of the target integer
     *
     * @param integer $num Integer whose value will be converted to a word-based string
     *
     * @return string Fully-built word-based representation of the target integer
     */
    public function int2str($num) {
        return trim($this->_integerToWords($num), "- \t\n\r\0\x0B");
    }
}
荆棘i 2024-08-25 08:06:41

pear 有一个包 Numbers_Words

$numberToWord = new Numbers_Words();
echo $numberToWords->toWords(200);

pear has a package Numbers_Words:

$numberToWord = new Numbers_Words();
echo $numberToWords->toWords(200);
丑丑阿 2024-08-25 08:06:41

并不是很理想,但至少比“巨大的 switch 语句”更好:

 $numbermappings = array("zero", "one","two","three", "four" .... "ninetynine");
 echo  $numbermappings[4]; // four

尽管如此,您仍然需要编写那个巨大的数组..

Not really ideal, but atleast better than a 'huge switch statement':

 $numbermappings = array("zero", "one","two","three", "four" .... "ninetynine");
 echo  $numbermappings[4]; // four

You still have to write that huge array though..

仅此而已 2024-08-25 08:06:41

这是我在大学时写的一篇文章。它还包括对负数的支持。我知道有一些方法可以缩短和/或清理它,但是嘿,它适用于任何整数!

/**
 Converts an integer to its textual representation.
 @param num the number to convert to a textual representation
 @param depth the number of times this has been recursed
*/
function readNumber($num, $depth=0)
{
    $num = (int)$num;
    $retval ="";
    if ($num < 0) // if it's any other negative, just flip it and call again
        return "negative " + readNumber(-$num, 0);
    if ($num > 99) // 100 and above
    {
        if ($num > 999) // 1000 and higher
            $retval .= readNumber($num/1000, $depth+3);

        $num %= 1000; // now we just need the last three digits
        if ($num > 99) // as long as the first digit is not zero
            $retval .= readNumber($num/100, 2)." hundred\n";
        $retval .=readNumber($num%100, 1); // our last two digits                       
    }
    else // from 0 to 99
    {
        $mod = floor($num / 10);
        if ($mod == 0) // ones place
        {
            if ($num == 1) $retval.="one";
            else if ($num == 2) $retval.="two";
            else if ($num == 3) $retval.="three";
            else if ($num == 4) $retval.="four";
            else if ($num == 5) $retval.="five";
            else if ($num == 6) $retval.="six";
            else if ($num == 7) $retval.="seven";
            else if ($num == 8) $retval.="eight";
            else if ($num == 9) $retval.="nine";
        }
        else if ($mod == 1) // if there's a one in the ten's place
        {
            if ($num == 10) $retval.="ten";
            else if ($num == 11) $retval.="eleven";
            else if ($num == 12) $retval.="twelve";
            else if ($num == 13) $retval.="thirteen";
            else if ($num == 14) $retval.="fourteen";
            else if ($num == 15) $retval.="fifteen";
            else if ($num == 16) $retval.="sixteen";
            else if ($num == 17) $retval.="seventeen";
            else if ($num == 18) $retval.="eighteen";
            else if ($num == 19) $retval.="nineteen";
        }
        else // if there's a different number in the ten's place
        {
            if ($mod == 2) $retval.="twenty ";
            else if ($mod == 3) $retval.="thirty ";
            else if ($mod == 4) $retval.="forty ";
            else if ($mod == 5) $retval.="fifty ";
            else if ($mod == 6) $retval.="sixty ";
            else if ($mod == 7) $retval.="seventy ";
            else if ($mod == 8) $retval.="eighty ";
            else if ($mod == 9) $retval.="ninety ";
            if (($num % 10) != 0)
            {
                $retval = rtrim($retval); //get rid of space at end
                $retval .= "-";
            }
            $retval.=readNumber($num % 10, 0);
        }
    }

    if ($num != 0)
    {
        if ($depth == 3)
            $retval.=" thousand\n";
        else if ($depth == 6)
            $retval.=" million\n";
        if ($depth == 9)
            $retval.=" billion\n";
    }
    return $retval;
}

Here's one I wrote way back in college. It includes support for negative numbers, as well. I know there's some ways it could be shortened and/or cleaned up, but hey, it works well for any integer!

/**
 Converts an integer to its textual representation.
 @param num the number to convert to a textual representation
 @param depth the number of times this has been recursed
*/
function readNumber($num, $depth=0)
{
    $num = (int)$num;
    $retval ="";
    if ($num < 0) // if it's any other negative, just flip it and call again
        return "negative " + readNumber(-$num, 0);
    if ($num > 99) // 100 and above
    {
        if ($num > 999) // 1000 and higher
            $retval .= readNumber($num/1000, $depth+3);

        $num %= 1000; // now we just need the last three digits
        if ($num > 99) // as long as the first digit is not zero
            $retval .= readNumber($num/100, 2)." hundred\n";
        $retval .=readNumber($num%100, 1); // our last two digits                       
    }
    else // from 0 to 99
    {
        $mod = floor($num / 10);
        if ($mod == 0) // ones place
        {
            if ($num == 1) $retval.="one";
            else if ($num == 2) $retval.="two";
            else if ($num == 3) $retval.="three";
            else if ($num == 4) $retval.="four";
            else if ($num == 5) $retval.="five";
            else if ($num == 6) $retval.="six";
            else if ($num == 7) $retval.="seven";
            else if ($num == 8) $retval.="eight";
            else if ($num == 9) $retval.="nine";
        }
        else if ($mod == 1) // if there's a one in the ten's place
        {
            if ($num == 10) $retval.="ten";
            else if ($num == 11) $retval.="eleven";
            else if ($num == 12) $retval.="twelve";
            else if ($num == 13) $retval.="thirteen";
            else if ($num == 14) $retval.="fourteen";
            else if ($num == 15) $retval.="fifteen";
            else if ($num == 16) $retval.="sixteen";
            else if ($num == 17) $retval.="seventeen";
            else if ($num == 18) $retval.="eighteen";
            else if ($num == 19) $retval.="nineteen";
        }
        else // if there's a different number in the ten's place
        {
            if ($mod == 2) $retval.="twenty ";
            else if ($mod == 3) $retval.="thirty ";
            else if ($mod == 4) $retval.="forty ";
            else if ($mod == 5) $retval.="fifty ";
            else if ($mod == 6) $retval.="sixty ";
            else if ($mod == 7) $retval.="seventy ";
            else if ($mod == 8) $retval.="eighty ";
            else if ($mod == 9) $retval.="ninety ";
            if (($num % 10) != 0)
            {
                $retval = rtrim($retval); //get rid of space at end
                $retval .= "-";
            }
            $retval.=readNumber($num % 10, 0);
        }
    }

    if ($num != 0)
    {
        if ($depth == 3)
            $retval.=" thousand\n";
        else if ($depth == 6)
            $retval.=" million\n";
        if ($depth == 9)
            $retval.=" billion\n";
    }
    return $retval;
}
柠北森屋 2024-08-25 08:06:41

****请参阅此函数的实际操作:****

function N2L($number)
{
    $result = array();
    $tens = floor($number / 10);
    $units = $number % 10;

    $words = array
    (
        'units' => array('', 'One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight', 'Nine', 'Ten', 'Eleven', 'Twelve', 'Thirteen', 'Fourteen', 'Fifteen', 'Sixteen', 'Seventeen', 'Eighteen', 'Nineteen'),
        'tens' => array('', '', 'Twenty', 'Thirty', 'Forty', 'Fifty', 'Sixty', 'Seventy', 'Eighty', 'Ninety')
    );

    if ($tens < 2)
    {
        $result[] = $words['units'][$tens * 10 + $units];
    }

    else
    {
        $result[] = $words['tens'][$tens];

        if ($units > 0)
        {
            $result[count($result) - 1] .= '-' . $words['units'][$units];
        }
    }

    if (empty($result[0]))
    {
        $result[0] = 'Zero';
    }

    return trim(implode(' ', $result));
}

****See this function in action:****

function N2L($number)
{
    $result = array();
    $tens = floor($number / 10);
    $units = $number % 10;

    $words = array
    (
        'units' => array('', 'One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight', 'Nine', 'Ten', 'Eleven', 'Twelve', 'Thirteen', 'Fourteen', 'Fifteen', 'Sixteen', 'Seventeen', 'Eighteen', 'Nineteen'),
        'tens' => array('', '', 'Twenty', 'Thirty', 'Forty', 'Fifty', 'Sixty', 'Seventy', 'Eighty', 'Ninety')
    );

    if ($tens < 2)
    {
        $result[] = $words['units'][$tens * 10 + $units];
    }

    else
    {
        $result[] = $words['tens'][$tens];

        if ($units > 0)
        {
            $result[count($result) - 1] .= '-' . $words['units'][$units];
        }
    }

    if (empty($result[0]))
    {
        $result[0] = 'Zero';
    }

    return trim(implode(' ', $result));
}
残花月 2024-08-25 08:06:41

如果您有来自 NumberFormatter 类.php.net/manual/en/book.intl.php" rel="noreferrer">intl 就在手边(你肯定会在 PHP>5.3 中这样做):

$nf = new NumberFormatter("en", NumberFormatter::SPELLOUT);
for ($i=0;$i<100;$i++) echo $nf->format($i)."\n";

当然,这也适用于 99 以上,对于您需要的任何语言(只需将第一个参数从“en”更改为任何内容)

If you have the NumberFormatter class from intl at hand (which you'll surely do in PHP>5.3):

$nf = new NumberFormatter("en", NumberFormatter::SPELLOUT);
for ($i=0;$i<100;$i++) echo $nf->format($i)."\n";

Of course, that also works over 99, and for any language you need (just change the first parameter from "en" to whatever)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文