Eski bir soru, ama başka herkes bu genelinde gelecek için ben bugün bu bir çözüm yazmak zorunda kaldım. Aşağıdaki John Kugelman tarafından açıklanan algoritmasına bir belli belirsiz benzer bir yaklaşım, ama sıkı bir dilbilgisi geçerli değildir; gibi bazı tuhaf orderings izin verir, örneğin "100.001 milyon 'hala" bir milyon ve yüz bini "(1,100,000) gibi aynı üretecek. Geçersiz bit (örn. yanlış numaralar) ihmal, böylece tanımsız olarak geçersiz dizeleri çıkışı dikkate alınacaktır.
Joebert cevabı üzerine user132513 yorumuna ardından, test serisi oluşturmak için Armut en Number_Words kullanılır. Aşağıdaki kod 0 ile 5000000 arasındaki numaraları 100% attı sonra 0 ve 10000000 arasında 100.000 numaraları rastgele bir numune üzerinde 100% (o bütün 10 milyar serisi üzerinde çalıştırmak için uzun sürer).
/**
* Convert a string such as "one hundred thousand" to 100000.00.
*
* @param string $data The numeric string.
*
* @return float or false on error
*/
function wordsToNumber($data) {
// Replace all number words with an equivalent numeric value
$data = strtr(
$data,
array(
'zero' => '0',
'a' => '1',
'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',
'fourty' => '40', // common misspelling
'fifty' => '50',
'sixty' => '60',
'seventy' => '70',
'eighty' => '80',
'ninety' => '90',
'hundred' => '100',
'thousand' => '1000',
'million' => '1000000',
'billion' => '1000000000',
'and' => '',
)
);
// Coerce all tokens to numbers
$parts = array_map(
function ($val) {
return floatval($val);
},
preg_split('/[\s-]+/', $data)
);
$stack = new SplStack; // Current work stack
$sum = 0; // Running total
$last = null;
foreach ($parts as $part) {
if (!$stack->isEmpty()) {
// We're part way through a phrase
if ($stack->top() > $part) {
// Decreasing step, e.g. from hundreds to ones
if ($last >= 1000) {
// If we drop from more than 1000 then we've finished the phrase
$sum += $stack->pop();
// This is the first element of a new phrase
$stack->push($part);
} else {
// Drop down from less than 1000, just addition
// e.g. "seventy one" -> "70 1" -> "70 + 1"
$stack->push($stack->pop() + $part);
}
} else {
// Increasing step, e.g ones to hundreds
$stack->push($stack->pop() * $part);
}
} else {
// This is the first element of a new phrase
$stack->push($part);
}
// Store the last processed part
$last = $part;
}
return $sum + $stack->pop();
}