【问题标题】:converting-words-to-numbers-in-php II在 php 中将单词转换为数字 II
【发布时间】:2012-11-30 18:55:12
【问题描述】:

这里有一个很棒的功能 Converting words to numbers in PHP 来自 El Yobo。 但我有一个问题,字符串必须以书面数字开头。 如何转换例如“iPhone 有二十三万七百八十三个应用程序”?

解释函数:

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();
}

【问题讨论】:

    标签: php numbers words


    【解决方案1】:

    嗯..我不得不承认..这对我个人来说很有趣!!!无论如何......这是代码......你可以在这里测试它:http://www.eyerollweb.com/str2digits/

    这是代码本身:

    <?php
    
    //The Test string
    $str = "two hundred thousand six hundred and two";
    
    $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,
        'fourty' => 40, // common misspelling
        'fifty' => 50,
        'sixty' => 60,
        'seventy' => 70,
        'eighty' => 80,
        'ninety' => 90,
        'hundred' => 100,
        'thousand' => 1000,
        'million' => 1000000,
        'billion' => 1000000000);
    
    //first we remove all unwanted characters... and keep the text
    $str = preg_replace("/[^a-zA-Z]+/", " ", $str);
    
    //now we explode them word by word... and loop through them
    $words = explode(" ", $str);
    
    //i devide each thousands in groups then add them at the end
    //For example 2,640,234 "two million six hundred and fourty thousand two hundred and thirty four"
    //is defined into 2,000,000 + 640,000 + 234
    
    //the $total will be the variable were we will add up to
    $total = 1;
    
    //flag to force the next operation to be an addition
    $force_addition = false;
    
    //hold the last digit we added/multiplied
    $last_digit = null;
    
    //the final_sum will be the array that will hold every portion "2000000,640000,234" which we will sum at the end to get the result
    $final_sum = array();
    
    foreach ($words as $word) {
    
        //if its not an and or a valid digit we skip this turn
        if (!isset($numbers[$word]) && $word != "and") {
            continue;
        }
    
        //all small letter to ease the comparaison
        $word = strtolower($word);
    
        //if it's an and .. and this is the first digit in the group we set the total = 0 
        //and force the next operation to be an addition
        if ($word == "and") {
            if ($last_digit === null) {
                $total = 0;
            }
            $force_addition = true;
        } else {
            //if its a digit and the force addition flag is on we sum
            if ($force_addition) {
                $total += $numbers[$word];
                $force_addition = false;
            } else {
                //if the last digit is bigger than the current digit we sum else we multiply
                //example twenty one => 20+1,  twenty hundred 20 * 100
                if ($last_digit !== null && $last_digit > $numbers[$word]) {
                    $total += $numbers[$word];
                } else {
                    $total *= $numbers[$word];
                }
            }
            $last_digit = $numbers[$word];
    
            //finally we distinguish a group by the word thousand, million, billion  >= 1000 ! 
            //we add the current total to the $final_sum array clear it and clear all other flags...
            if ($numbers[$word] >= 1000) {
                $final_sum[] = $total;
                $last_digit = null;
                $force_addition = false;
                $total = 1;
            }
        }
    
    
    
    }
    
    // there is your final answer !
    $final_sum[] = $total;
    print "Final Answer: " . array_sum($final_sum) . "\n";
    
    ?>
    

    【讨论】:

    • 我什至可以编辑它的代码以检测同一字符串中的多个数字“一组数字”......例如:“这是我可以说一个然后过一会儿的句子再说两百来得到一些很棒的结果”,返回值将是 1, 200 :)
    【解决方案2】:
    $input = "iPhone has two hundred and thirty thousand, seven hundred and eighty-three apps";
    $words = explode(' ', preg_replace("/[^A-Za-z0-9]/", ' ', $input)); //replace non-alpha characters like ',' with ' '
    $res_arr = array();
    
    foreach( $input_arr as $word ) {
        if( in_array($word, $number_words) ) { //$number_words being the large array given in your code
            $res_arr[] = $word;
        }
    }
    $clean_input = implode(' ', $res_arr);
    //should look like: two hundred and thirty thousand seven hundred and eighty-three
    

    【讨论】:

      【解决方案3】:
      <?php
      $val = '';
      if(isset($_POST['submit']))
      {
          $val_entered = str_replace(',','',$_POST['nmbr']);
          $num_list = explode('.',$val_entered);
          $full_val = convert_num($num_list[0]);$cnxn = '';
          if($num_list[0]!=0){$cnxn = ' and ';}
      
          $dec_val = convert_num($num_list[1]);
          $val=' Value entered  is '.$val_entered.' =  Rupees '.$full_val.$cnxn.' cents '.$dec_val;
      
      }
      ?>
      <form name="cnvt" id="cnvt" action="" method="post">
      <input type="text" id="nmbr" name="nmbr" value="0" />
      <input type="submit" id="submit" name="submit" value="Submit"  />
      </form>
      <?php print  $val ?>
      
      <?php
      function convert_num($nmbr)
      {
          $numword = 'Zero';
          if($nmbr>0)
          {
          $abacus = setto_abacus($nmbr);
          //print '<pre>';print_r($abacus);print '</pre>';
          $numword = read_abacus($abacus);
          }
      
          return $numword;
      
      }
      function setto_abacus($nmbr)
      {
          $abacus = array(1000000=>0,1000=>0,100=>0,1=>0);
          $val = $nmbr; //2,500,605
          foreach(array_keys($abacus)as $key)
          {
              $abacus[$key] = (int)($val/$key);
              $val = $val %$key;
          }
          return $abacus;
      }
      function read_abacus($abacus)
      {
          $position_name = array(100=>'Hundred',1000=>'Thousand',1000000=>'Million');
          $numvals = array(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=>'Forty',50=>'Fifty',60=>'Sixty',70=>'Seventy',80=>'Eighty',90=>'Ninety');
          $num_words = ""; $cnxn = '';
          foreach($abacus as $key=>$val)
          {
              $cnxn = ''; if($key==1 && $num_words !=''){$cnxn='and';}
              if($val>0)
              {
                  if($val>=100)
                  {   $rfnum = (int)($val/100);
                      $num_words.= $numvals[$rfnum].' '.$position_name[100].' ';
                      $rfnum = $val % 100;
                  }
                  else
                  {
                      $rfnum = $val;
                  }
                  if($rfnum>0)
                  {   
                      $num_words.= get_twodigit_inwords($rfnum, $cnxn);
                  }
                  $num_words.= ' '.$position_name[$key].' ';
      
              }
      
          }
          return $num_words;
      }
      function get_twodigit_inwords($rfnum, $cnxn)
      {
          $numvals = array(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=>'Forty',50=>'Fifty',60=>'Sixty',70=>'Seventy',80=>'Eighty',90=>'Ninety');
          $tens_words = '';$unit_words = '';
      
          if($rfnum>0)
          {   
              if(array_key_exists($rfnum,$numvals))
              {
                  $tens_words= $numvals[$rfnum].' ';
              }
              else 
              {
                  $tens_words = $numvals[(int)($rfnum /10)*10];
                  $unit_words = $numvals[$rfnum %10];
              }
          }
          $twodigit_name = $cnxn.' '.$tens_words.' '.$unit_words;
          return $twodigit_name;
      }
      
      ?>
      

      【讨论】:

        【解决方案4】:
        <?php
        
        $string=$_POST['num'];
        $array1=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,"sixteen"=>16,"seventeen"=>17,"eighteen"=>18,"ninteen"=>19,"twenty"=>20,"thirty"=>30,"fourty"=>40,"fifty"=>50,"sixty"=>60,"seventy"=>70,"eighty"=>80,"ninty"=>90);
        
        $array2=array("hundred"=>100,"thousand"=>1000,"lakh"=>100000,"crore"=>10000000);
        echo "<br>";
        $number=explode(" ",$string);
        echo "<br>";
        $count=count($number);
        $new=0;
        $final=0;
        foreach($number as $word)
        {
            $lastTwo=$lastOne;
            foreach($array1 as $keyCN=>$valueCN)
            {   
        
                if($keyCN==$word)
                {
                    $new=$valueCN;
                    $lastOne=$valueCN;
                }
             }
        
            foreach($array2 as $key=>$value)
            {
                 if($key==$word)
                 {
        
                    $new2=$new*$value;
                    $num+=$new2;
                    $lastOne=0;
                    $lastTwo=0;
                }
            }   
        }
        $final=$num+$lastOne+$lastTwo;
        
        echo "final is $final<br>";
        ?>
        <form method="POST">
        <input type="text" name="num" value=""></br>
        <input type="submit" value="Convert string to number">
        </form>             
        

        【讨论】:

          【解决方案5】:

          应该是这样的

          $numbers = array('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", '21' => "twenty one", '22' => "twenty two", '23' => "twenty three", '24' => "twenty four", '25' => "twenty five", '26' => "twenty six", '27' => "twenty seven", '28' => "twenty eight", '29' => "twenty nine", '30' => "thirty", '31' => "thirty one", '32' => "thirty two", '33' => "thirty three", '34' => "thirty four", '35' => "thirty five", '36' => "thirty six", '37' => "thirty seven", '38' => "thirty eight", '39' => "thirty nine", '40' => "fourty", '41' => "fourty one", '42' => "fourty two", '43' => "fourty three", '44' => "fourty four", '45' => "fourty five", '46' => "fourty six", '47' => "fourty seven", '48' => "fourty eight", '49' => "fourty nine", '50' => "fifty", '51' => "fifty one", '52' => "fifty two", '53' => "fifty three", '54' => "fifty four", '55' => "fifty five", '56' => "fifty six", '57' => "fifty seven", '58' => "fifty eight", '59' => "fifty nine", '60' => "sixty", '61' => "sixty one", '62' => "sixty two", '63' => "sixty three", '64' => "sixty four", '65' => "sixty five", '66' => "sixty six", '67' => "sixty seven", '68' => "sixty eight", '69' => "sixty nine", '70' => "seventy", '71' => "seventy one", '72' => "seventy two", '73' => "seventy three", '74' => "seventy four", '75' => "seventy five", '76' => "seventy six", '77' => "seventy seven", '78' => "seventy eight", '79' => "seventy nine", '80' => "eighty", '81' => "eighty one", '82' => "eighty two", '83' => "eighty three", '84' => "eighty four", '85' => "eighty five", '86' => "eighty six", '87' => "eighty seven", '88' => "eighty eight", '89' => "eighty nine", '90' => "ninety", '91' => "ninety one", '92' => "ninety two", '93' => "ninety three", '94' => "ninety four", '95' => "ninety five", '96' => "ninety six", '97' => "ninety seven", '98' => "ninety eight", '99' => "ninety nine", '100' => 'hundred', '1000' => 'thousand', '1000000' => 'million');
          
          $words = explode(" ", $string);
          
          $sw = 0;
          $words = array_merge($words);
          
          
          
          
          for ($nindex = 0; $nindex < count($words); $nindex++) {
          
              $numword = $words[$nindex];
              $preservenumword = $numword;
          
          
              if ($numword == "one hundred") {
                  $numword = "hundred";
                  $words[$nindex] = $numword;
              }
              if ($numword == "one thousand") {
                  $numword = "thousand";
                  $words[$nindex] = $numword;
              }
              if ($numword == "one million") {
                  $numword = "million";
                  $words[$nindex] = $numword;
              }
          
          
              $numwordarray = array_search(strtolower($numword), $numbers);
          
              if ($numwordarray === false || $numwordarray == 0 || $numwordarray == "") {
                  unset($words[$nindex]);
              }
          }
          
          $finalNumber = 0;
          
          for ($nindex = 0; $nindex < count($words); $nindex++) {
          
          
              $number = array_search(strtolower($words[$nindex]), $numbers);
              if ($number === false || $number == 0 || $number == "")
                  continue;
          
              $cur = strtolower($words[$nindex]);
              if ($nindex + 1 >= count($words))
                  $next = '';
              else
                  $next = strtolower($words[$nindex + 1]);
              $coupleword = $cur . " " . $next;
              $couplenumber = array_search($coupleword, $numbers);
          
              if ($couplenumber != false && $couplenumber != 0 && $couplenumber != "") {
                  if (strtolower($words[$nindex + 2]) == "hundred") {
                      $finalNumber = $finalNumber + ($couplenumber * 100);
          
                      $nindex+=2;
                  } elseif (strtolower($words[$nindex + 2]) == "thousand") {
          
                      $finalNumber = ($finalNumber + $couplenumber) * 1000;
          
                      $nindex+=2;
                  } else {
                      $finalNumber = $finalNumber + $couplenumber;
          
                      $nindex++;
                  }
          
                  continue;
              }
          
          
              if (strtolower($words[$nindex]) != "thousand" && strtolower($words[$nindex + 1]) == "hundred") {
                  $finalNumber = $finalNumber + ($number * 100);
                  $nindex++;
          
                  continue;
              } else if (strtolower($words[$nindex + 1]) == "thousand" && strtolower($words[$nindex]) != "hundred") {
                  $finalNumber = $finalNumber + ($number * 1000);
                  $nindex++;
          
                  continue;
              } else if (strtolower($words[$nindex]) == "thousand") {
                  $finalNumber = $finalNumber * 1000;
          
                  continue;
              } else if (strtolower($words[$nindex]) == "hundred") {
                  $finalNumber = $finalNumber * 100;
          
                  continue;
              } else if (strtolower($words[$nindex]) == "million") {
                  $finalNumber = $finalNumber * 1000000;
          
                  continue;
              } else {
                  $finalNumber = $finalNumber + $number;
              }
          }
          
          echo $finalNumber;
          

          【讨论】:

            猜你喜欢
            • 2010-11-07
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多