1

Possible Duplicate:
Converting words to numbers in PHP

Is there a php function to convert a string such as 'ten' into an integer?
If not then how would you go about it?
Have tried google and php.net search with no success

Community
  • 1
  • 1
andrew
  • 5,096
  • 10
  • 43
  • 57
  • 1
    possible duplicate of [Converting words to numbers in PHP](http://stackoverflow.com/questions/1077600/converting-words-to-numbers-in-php) - There are two good references there. The first is an algorithm for implementing one yourself, and the other is a pre-built tool to do it... – ircmaxell Nov 15 '10 at 21:59
  • I had actually assumed that php had a build in function for converting strings into numbers since it is quite a powerful language. If there is no built in function then I don't think it would be worth the effort. – andrew Nov 15 '10 at 22:24
  • See also: ["How to read values from numbers written as words?"](http://stackoverflow.com/questions/70161/how-to-read-values-from-numbers-written-as-words). – outis Nov 15 '10 at 22:41
  • You know, I think that's the first time I've seen "PHP" and "powerful" in the same sentence that didn't also include a comparison to almost dead batteries. – outis Nov 15 '10 at 22:43
  • PHP is very powerful (it's Turing complete after all)... Sure, it's commonly abused, and is sometimes difficult to extract the power, but it's there... – ircmaxell Nov 15 '10 at 23:39

3 Answers3

7

Here's a proof of concept class that I just wrote to do this... Check it out:

class WordToNumber {

    public $modifiers = array(
        'hundred' => 100,
    );

    public $negatives = array(
        'minus' => true,
        'negative' => true,
    );

    public $numbers = array(
        'zero'  => 0,
        'one'   => 1,
        'two'   => 2,
        'three' => 3,
        'four'  => 4,
        'five'  => 5,
        'six'   => 6,
        'seven' => 7,
        'eight' => 8,
        'nine'  => 9,
        'ten'   => 10,
        'eleven' => 11,
        'twelve' => 12,
        'thirteen' => 13,
        'fourteen' => 14,
        'fifteen'  => 15,
        'sixteen'  => 16,
        'seventeen' => 17,
        'eighteen'  => 18,
        'nineteen'  => 19,
        'twenty'    => 20,
        'thirty'    => 30,
        'forty'    => 40,
        'fifty'     => 50,
        'sixty'     => 60,
        'seventy'   => 70,
        'eighty'    => 80,
        'ninety'    => 90,    
    );

    public $powers = array(
        'thousand' => 1000,
        'million'  => 1000000,
        'billion'  => 1000000000,
    );

    public function __construct() {
    }

    public function parse($string) {
        $string = $this->prepare($string);
        $parts = preg_split('#\s+#', $string, -1, PREG_SPLIT_NO_EMPTY);
        $buffer = 0;
        $lastPower = 1;
        $powers = array(
            1 => 0,
        );
        $isNegative = false;
        foreach ($parts as $part) {
            if (isset($this->negatives[$part])) {
                $isNegative = true;
            } elseif (isset($this->numbers[$part])) {
                $buffer += $this->numbers[$part];
            } elseif (isset($this->modifiers[$part])) {
                $buffer *= $this->modifiers[$part];
            } elseif (isset($this->powers[$part])) {
                if ($buffer == 0) {
                    //Modify last power
                    $buffer = $powers[$lastPower];
                    unset($powers[$lastPower]);
                    $power = $lastPower * $this->powers[$part];
                    $powers[$power] = $buffer;
                    $lastPower = $power;
                    $buffer = 0;
                } else {
                    $powers[$this->powers[$part]] = $buffer;
                    $buffer = 0;
                    $lastPower = $this->powers[$part];
                }
            } else {
                throw new LogicException('Unknown Token Found: '.$part);
            }
        }
        if (!empty($buffer)) {
            $powers[1] = $buffer;
        }
        $total = 0;
        foreach ($powers as $power => $sub) {
            $total += $power * $sub;
        }
        if ($isNegative) {
            $total *= -1;
        }
        return $total;
    }

    protected function prepare($string) {
        $string = preg_replace('#(\s+|-|\band\b)#i', ' ', $string);
        $string = mb_convert_case($string, MB_CASE_LOWER);
        return $string;
    }

}

And a test:

$parser = new WordToNumber();

$strings = array(
    'one hundred and fifty two',
    'fifteen',
    'one thousand million',
    'four hundred thousand five hundred fourty three',
    'fifteen hundred',
    'one thousand twelve hundred',
    'negative two',
    'minus three hundred and fifty seven thousand four hundred and two',
);

foreach ($strings as $str) {
    echo $parser->parse($str).' - '.$str."\n";
}

And the results:

152 - one hundred and fifty two
15 - fifteen
1000000000 - one thousand million
400543 - four hundred thousand five hundred fourty three
1500 - fifteen hundred
2200 - one thousand twelve hundred
-2 - negative two
-357402 - minus three hundred and fifty seven thousand four hundred and two

It doesn't support huge numbers (hence why billion is the largest power), but it should be trivially modified to support them by using the bcmath extension... If you want, I could quickly modify it to work with numbers as high as you want.

ircmaxell
  • 163,128
  • 34
  • 264
  • 314
2
function smallTextIntToDigits($x)
{
   $lilx = lcase($x)
   $data = array('one'=>1,'two'=>2,'three'=>3,'four'=>4,'five'=>5,'six'=>6,'seven'=>7,'eight'=>8,'nine'=>9,'ten'=>10,'eleven'=>11,'twelve'=>12,'thirteen'=>13,'fourteen'=>14,'fifteen'=>15);
   if (isset($data[$lilx])) 
       return $data[$lilx];
   elseif (isset(data[lcase(str_replace('teen', '', $x))]) 
       return data[(str_replace('teen', '', lcase($x))] + 10;

   return -1; //harder stuff, recurse on big ones.  blah blah blah
}
jon_darkstar
  • 16,398
  • 7
  • 29
  • 37
1

You can use an associative array (aka hash) to contain the values you expect. For example:

$assoc_arr = array("one" => 1, "ten" => 10);
$my_ans = $assoc_arr["ten"] + 5;
GreenMatt
  • 18,244
  • 7
  • 53
  • 79
  • This would be best for a simple solution, ie if you only have to do convert a handful of values. If you want to convert arbitrary strings into digits you'll have to start with defining a grammar.. – user318904 Nov 15 '10 at 22:03
  • True, but it's not clear how complex the answer needs to be. – GreenMatt Nov 15 '10 at 22:23