【问题标题】:Converting a number in English to its digital value (ignore decimals)将英文数字转换为其数字值(忽略小数)
【发布时间】:2015-10-13 17:35:20
【问题描述】:

我想将“300 万”、“24000”、“350000”等这些类型的值转换为数字。在 JavaScript(所以我可以在客户端)或 PHP(服务器端)中。有这个功能吗?喜欢 PHP 的 strtotime() 函数?

input                  output
3 million              3000000
24 thousand            24000
350 thousand           350000

【问题讨论】:

  • 我不知道有这样的功能。不过,您可以破解它。做类似['million' => '000000'...etc'] 的事情,但这真的很容易出错。
  • 我不完全确定这是重复的,但它似乎相关:stackoverflow.com/questions/11980087/…
  • 我认为唯一的方法是在评论一中提到

标签: javascript php converter


【解决方案1】:
    $str = str_replace('hundred','00',$str);
    $str = str_replace('thousand','000',$str);
    $str = str_replace('million','000000',$str);
    $str = str_replace('billion','000000000',$str);
$str = str_replace(' ','',$str);

像这样:)

【讨论】:

    【解决方案2】:

    你也想合并它们吗?

    function convert(num) {
      function mapGroups(str) {
        if (/million/.test(str)) {
          return str.match(/\d+/)[0] * 1000000;
        }
        if (/thousand/.test(str)) {
          return str.match(/\d+/)[0] * 1000;
        }
        if (/hundred/.test(str)) {
          return str.match(/\d+/)[0] * 100;
        }
        return +str;
      }
      
      return num.match(/(\d+)( ?\w* ?)/g)
                .map(mapGroups)
                .reduce(function(p, c) { return p + c });
    }
    
    console.log(convert("3 million 240 thousand 7 hundred 54")) //3240754
    console.log(convert("5 millions 7 hundreds 54")) //5000754

    这是非常基本的,但你确实掌握了。

    【讨论】:

      【解决方案3】:

      没有奇迹般的解决方案,但NumberFormatter::parse PHP 函数可以帮助您解决问题:

      $fmt = numfmt_create('en_US', NumberFormatter::SPELLOUT);
      echo numfmt_format($fmt, '1234567');
      

      将输出1234567

      $fmt = numfmt_create('en_US', NumberFormatter::SPELLOUT);
      echo numfmt_parse($fmt, 'one million two hundred thirty-four thousand five hundred sixty-seven');
      

      将输出1234567

      遗憾的是,这不适用于像“24,000”这样的混合类型值(它需要完全拼出),但您可以通过首先拼出字符串中的实际数字来组合一种解决方法。

      【讨论】:

        【解决方案4】:

        假设:

        1. 您的数字部分始终以数字格式书写
        2. 单位一致且拼写正确,即您始终使用“million”而不是“millions”或“milion”
        3. 数字语法正确(例如 300 万、24000、ecc)

        你可以使用这样的地图:

        var unitMap = [million:6, thousand:3, '':1] // add as many units as you like
        

        然后将字符串转换为数字。这是一个使用 javascript 和 jQuery 的想法。

        var UNIT_SEPARATOR = ', '; // what separates the number parts (millions from thousands, ecc)
        var VALUE_UNIT_SEPARATOR = ' '; // what goes between the value and the unit
        var unitMap = {
            billion:9,
            million:6,
            thousand:3,
            '':1
        }; // add as many units as you like
        
        $('#convert').click(function () {
            var number = $('#input').val();
            var numberParts = number.split(UNIT_SEPARATOR);
            var convertedNumber = 0;
        
            for (var i = 0; i < numberParts.length; i++) {
                var splitUnit = numberParts[i].split(' ');
                var value = parseFloat(splitUnit[0]);
                var exp = (splitUnit.length === 1) ? 0 : parseInt(unitMap[splitUnit[1]]);
        
                var temp = value * Math.pow(10, exp);
        
                convertedNumber += temp;
            }
        
            $('#result').text(convertedNumber);
        });
        

        Here's the fiddle

        注意这是一个提示。在使用它之前,应该对输入进行清理和验证。此外,这种方法非常容易出错,因此您应该在应用之前仔细测试它(参见上述假设)。

        希望对您有所帮助! ;)

        【讨论】:

          【解决方案5】:

          这个示例是为了将数字转换为单词而编写的,但在许多情况下您可以将单词转换为数字 - 只要输入的单词与从数字到单词计算的输出相匹配。

          欢迎你拿走你能用的,把剩下的扔掉。

          <!doctype html>
          <html lang= "en">
          <head>
          <meta charset= "utf-8">
          <title>Number Strings</title>
          <style>
          textarea{
              font-size: 1em;
              color: black;
              font-weight: 600;
              resize: both;
          }
          button{
              cursor: pointer;
              text-decoration: none;
              color: black;
              font-size: 1em;
              font-weight: bold;
          }
          button: hover, button: focus{
              color: red;
          }
          p{
              font-size: 1.1em;
              font-weight: 500;
              position: relative;
              margin: 1em 1ex;
          }
          .leftcolumnDiv{
              display: inline-block;
              position: relative;
              max-width: 60em;
              min-width: 24em;
              border: thick navy ridge;
              border-radius: 1em;
              padding: 1em;
          }
          #numword_div{
              color: black;
              font-weight: 600;
              font-size: 1em;
              padding: 1em;
              font-family: sans-serif;
          }
          #numword_div span{
              color: green;
          }
          </style>
          
          <script>
          // utility for display demo and object container for number/word methods
          
          function mr(hoo){
              if(typeof hoo== 'string') hoo= document.getElementById(hoo) || '';
              return (hoo.nodeType== 1)? hoo: null;
          }
          
          var Yankee= {
              dr: function(what, pa, hoo, txt, sty){
                  var tag, el, mod, ref;
                  what= what.toLowerCase().split('_');
                  tag= what[0], mod= what[1], ref= mr(pa);
                  el= document.createElement(tag);
                  if(hoo) el.id= hoo;
                  if(sty) el.style.cssText= sty;
                  if(ref){
                      if(mod== 'b4') ref.parentNode.insertBefore(el, ref);
                      else if(mod== 'bf' && ref.firstChild){
                          ref.insertBefore(el, ref.firstChild);
                      }
                      else ref.appendChild(el);
                  }
                  if(txt) el.appendChild(document.createTextNode(txt));
                  return el;
              },
              zap: function(who){
                  who= mr(who);
                  while(who.lastChild) who.removeChild(who.lastChild);
              },
              zappit:function(who){
                  who= mr(who);
                  who.parentNode.removeChild(who);
              }
          }
          
          /* US English words from numbers and back*/
          Math.gcd= function gcd(a, b){
              if(b) return gcd(b, a%b);
              return Math.abs(a);
          }
          Number.fromRoman= function(s){
              s= String(s).toUpperCase();
              if(s.length>15 ||  /[^MDCLXVI]/.test(s)) return NaN;
              var L= s.length, sum= 0, i= 0, next, val, 
              R={
                  M: 1000, D: 500, C: 100, L: 50, X: 10, V: 5, I: 1
              };
              while(i<L){
                  val= s.charAt(i++);
                  if(!R[val]) return NaN;
                  val= R[val];
                  next= R[(s.charAt(i) || 'N')] || 0;
                  if(next>val) val*= -1;
                  sum+= val;
              }
              if(sum.toRoman()== s) return sum;
              return NaN;
          }
          Number.prototype.toRoman= function(){
              var n= Math.floor(this), val, s= '', limit= 3999, i= 0, 
              v= [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1], 
              r= ['M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I'];
              if(n<1 || n>limit) return '';
              while(i<13){
                  val= v[i];
                  while(n>= val){
                      n-= val;
                      s+= r[i];
                  }
                  if(n== 0) return s;
                  ++i;
              }
              return '';
          }
          
          Yankee.NW={
              nameNumbers: function(str){
                  var Y= Yankee.NW, nw= Y.numberWords, 
                  s= (str+'').replace(/([^\d])(?=\.\d+)/g, '$1 0').trim();
                  var f, w= '', x, xs, n, ns, M, 
                  rx=/(-?\d+)(\.(\d+)([eE]([+-]?\d+))?)?/g, 
                  rx2=/(\d+)(\.(\d+)([eE]([+-]?\d+))?)?/, 
                  rq=/((\d+)? +(and +)?)?(\d+)\/(\d+)/g;
                  s= s.replace(rq, function(a){
                      return Y.printFraction(a);
                  });
                  s= s.replace(rx, function(q){
                      n= +q, 
                      ns= n+'';
                      M= rx2.exec(ns) || [];
                      w= (n<0)? 'minus ': '';
                      if(M[1]) w+= nw(M[1]);
                      if(M[3]){
                          f= M[3].split('').map(function(itm){
                              return nw(itm);
                          });
                          w+= ' point '+ f.join(' ');
                          if(M[5]){
                              x= +M[5];
                              xs= x<0? 'minus ': '';
                              xs+= Y.ordinal(nw(x));
                              w+= ' times ten to the '+xs;
                          }
                      }
                      return w || q;
                  });
                  return s.replace(/ {2,}/g, ' ');
              },
              numberWords: function numberWords(x){
                  var n= +x;
                  if(isNaN(n) || n%1) return ''+x;
                  n= Math.abs(n);
                  var i= 0, p, prefix= [], num, rem, 
                  NK= Yankee.NW.numberwords_array, 
                  w= NK[0], w1= NK[1], w2= NK[2], mag= NK[3];
                  while(n>99){
                      x= mag[i];
                      if(n>= x){
                          p= Math.floor(n/x);
                          n%= x;
                          prefix.push(numberWords(p)+w2[i]);
                      }
                      ++i;
                  }
                  if(prefix.length){
                      prefix= prefix.join(', ');
                      if(n) prefix+= ' and ';
                      else return prefix;
                  }
                  else prefix= '';
                  if(n<20) num= w[n];
                  else{
                      num= w1[Math.floor(n/10)];
                      rem= n%10;
                      if(rem) num+= ' '+w[rem];
                  }
                  return prefix+num;
              },
              numberwords_array: [
                  ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 
                  'eight', 'nine', 'ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 
                  'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen'], 
                  ['', '', 'twenty', 'thirty', 'forty', 'fifty', 'sixty', 
                  'seventy', 'eighty', 'ninety'], 
                  [' quadrillion', ' trillion', ' billion', ' million', 
                  ' thousand', ' hundred'], 
                  [1e15, 1e12, 1e9, 1e6, 1e3, 100]
              ], 
              ordinal: function(s){
                  var ax, rx, suffix, str= ' '+s.trim();
                  ax= str.lastIndexOf(' ');
                  suffix= str.substring(ax).toLowerCase();
                  if(str.charAt(str.length-1)== 'y'){
                      return str.slice(0, -2)+'tieth';
                  }
                  if(ax>1) str= str.substring(0, ax);
                  else str= ' ';
                  switch(suffix.trim()){
                      case 'one': return str+' first';
                      case 'two': return str+' second';
                      case 'three': return str+' third';
                      case 'five': return str+' fifth';
                      case 'eight': return str+' eighth';
                      case 'nine': return str+' ninth';
                      case 'twelve': return str+' twelfth';
                      default: return str+suffix+'th';
                  }
              },
              printFraction: function(s){
                  var str= s.replace('and ', '').trim()
                  var num, Y= Yankee.NW, RN= Y.numberWords, 
                  M=/((\d+)? +)?(\d+)\/(\d+)/.exec(str);
                  if(!M) return str;
                  num= M[2]? RN(M[2])+' and ': '';
                  num+= RN(+M[3])+'-';
                  if(M[4]=== '2') num+= 'half';
                  else if(M[4]=== '4') num+= 'quarter';
                  else num+= Y.ordinal(RN(+M[4]));
                  if(M[3]!== '1') num+= 's';
                  return num;
              },
              /* words to numbers */
              fromFraction: function(str, prec){
                  var rx=/(\d+)\/(\d+)/, dec= 0, I= 0, 
                  M= rx.exec(str);
                  if(M){
                      if(M.index>0) I= parseFloat(str);
                      if(M[1]) dec= M[1]/M[2];
                      if(!prec) prec= str.length+1;
                      if(typeof prec== 'number') dec= +(dec.toFixed(prec));
                      return I+dec;
                  }
                  return parseFloat(str);
              },
              reDigit: function(n){
                  var sub= [], tem, d= n.match(/[a-z]+/g), L= d.length-1, 
                  nwords= Yankee.NW.wordnumber_keys;
                  d.map(function(w, i){
                      tem= nwords[w];
                      if(isFinite(tem)){
                          if(tem<20 || i== L) sub.push(tem+'');
                          else sub.push((tem+'').charAt(0));
                      }
                  });
                  return sub.join('');
              },
              reFraction: function(str){
                  var M, w= 0, n, d, f2= 0, prec, ax;
                  ax= str.lastIndexOf(' and ');
                  if(ax== -1){
                      ax= 0;
                      w= 'zero';
                  }
                  else{
                      w= str.substring(0, ax);
                      ax+= 4;
                  }
                  M= str.substring(ax).split('-');
                  n= M[0];
                  d= M[1];
                  if(n && d){
                      d= Yankee.NW.wordsToNumber(d);
                      n= Yankee.NW.wordsToNumber(n);
                      return [w, n/d];
                  }
                  return [w];
              },
              wordNumber: function(str){
                  var Y= Yankee.NW, n= 0, sign= 1, whole= 0, dec= 0, frac, 
                  suffix= 0, exp= 1, exsign= 1, prec, pt, 
                  rx1=  /(illion|thousand|hundred)/i, 
                  rx2=/( +times ten to the( +minus)? +)/g, 
                  rx3=/(point|times|[^a-z, ])/, 
                  s= str.toLowerCase().trim().replace(/ieth?$/, 'y').replace(/(ths?|s)$/, '');
                  if(s.indexOf('minus ')== 0){
                      sign= -1;
                      s= s.substring(5);
                  }
                  if(!rx3.test(s)){
                      n= (!rx1.test(s))? Y.reDigit(s): Y.wordsToNumber(s);
                      return n*sign;
                  }
                  whole= s;
                  var pt= s.split('point ');
                  dec= pt[1];
                  if(dec){
                      whole= pt[0];
                      temp= rx2.exec(dec);
                      if(temp!= null){
                          if(temp[2]) exsign= -1;
                          suffix= dec.substring(rx2.lastIndex);
                          dec= dec.substring(0, temp.index);
                          suffix= Y.wordsToNumber(suffix);
                          exp= Math.pow(10, suffix*exsign);
                      }
                      dec= Y.reDigit(dec);
                      prec= dec.length+1;
                      dec= +('0.'+dec);
                  }
                  else if(whole.indexOf('-')!= -1){
                      pt= Y.reFraction(whole);
                      whole= pt[0];
                      dec= pt[1];
                  }
                  n= Y.wordsToNumber(whole.replace(/ +and +/g, ' '));
                  if(dec){
                      n+= dec;
                      if(!prec) frac= Math.min(String(n).length, 15);
                      n= n.toPrecision(frac);
                  }
                  if(exp!== 1) return sign*((n*exp).toExponential(prec));
                  return sign*n;
              },
              wordnumber_keys:{
                  billion: 1e9, eigh: 8, eight: 8, eighteen: 18, eightt: 8, eighty: 80, 
                  eleven: 11, fif: 5, fifteen: 15, fifty: 50, first: 1, five: 5, forty: 40, 
                  four: 4, fourteen: 14, half: 2, hundred: 100, million: 1e6, nin: 9, 
                  nine: 9, nineteen: 19, ninety: 90, one: 1, quadrillion: 1e15, quarter: 4, 
                  second: 2, seven: 7, seventeen: 17, seventy: 70, six: 6, sixteen: 16, 
                  sixty: 60, ten: 10, third: 3, thirteen: 13, thirty: 30, thousand: 1e3, 
                  three: 3, trillion: 1e12, twelf: 12, twelve: 12, twenty: 20, two: 2, zero: 0
              },
              wordsToNumber: function(s){
                  var w= s.toLowerCase().replace(/(thousand|[mbr]illion),?/g, '$1,');
                  var n= 0, nArray= w.split(/,/), 
                  sub= 0, tem, segment, 
                  nwords= Yankee.NW.wordnumber_keys;
                  while(nArray.length){
                      sub= 0;
                      segment= nArray.shift().match(/[a-z]+/g) || [];
                      segment.forEach(function(w2){
                          tem= nwords[w2.trim()];
                          if(isFinite(tem)){
                              if(tem<100) sub+= tem;
                              else sub*= tem;
                          }
                      });
                      n+= sub;
                  }
                  return n;
              },
              //demo
              display: function(skip){
                  var who= mr('strum_in'), nw= Yankee.NW, 
                  v= who.value.trim(), v2, n2, p, w= '';
                  if(!/[a-z\d]+/i.test(v)) return;
                  var didit= mr('numword_div').textContent || mr('numword_div').innerText||'';
                  if(didit.indexOf(who.value+'=')== 0) return;
                  if(/^[IVXLCDM]+$/.test(v)) v= Number.fromRoman(v);
                  if(/^[a-z ,-]+$/i.test(v)){
                      v2= nw.wordNumber(v);
                  }
                  else v2= nw.nameNumbers(v);
                  p= Yankee.dr('p_bf', 'numword_div', '', who.value+'= ');
                  Yankee.dr('span', p, '', v2, 'color:green');
                  mr('numword_div').scrollTop= 0;
                  mr('strum_in').focus();
              },
              sampler: function(){
                  var nw= Yankee.NW, v2, v;
                  Yankee.zap('numword_div');
                  mr('strum_in').value= '';
                  var A= ['150', '0.12', 'fourteen hundred and ninety two', '65 1/16', '65.0045', 
                  'thirty three and one- third', '2012', '98.6', 'MCMLIX', '897456971.25', 
                  '1 1/2', '12 3/4', '-9', '33 1/3', Math.PI, 'nine and three- quarters', 
                  'seventy eight point six four','XIX',  '1.1550046210e+17', '1.222e3', 'minus two hundred', 
                  '4.5e-10', '3.125e-3', '1.56760e+25'].forEach(function(sv){
                      mr('strum_in').value= sv;
                      nw.display();
                  });
                  mr('numword_div').scrollTop= 0;
                  mr('strum_in').focus()
              }
          }
          window.onload= function(){
              mr('toWordsBtn').onclick= Yankee.NW.display;
              mr('demoWordsBtn').onclick= Yankee.NW.sampler;
              mr('clearWordsBtn').onclick= function(){
                  Yankee.zap('numword_div');
                  mr('strum_in').focus();
              }
          }
          </script>
          </head>
          <body>
          <p class= "breadcrumbs"><a href= "../webshop.html">Home</a> </p>
          <h1>Numbers to Words, Words to Numbers<br>
          <span style= "font-weight: bold; color: navy; font-size:smaller">US- English version</span> </h1>
          <div class= "leftcolumnDiv">
          <p>Besides digits, numerical input can include a negative sign(-50), 
          decimal point(.), exponential(1.15e+25) or a real number with a division slash(1/2 or 9 3/4).</p>
          <p>You can also find a number value from word input, if the words are formed
          as the parser expects.(Any output word strings can be used as input.)</p>
          <h3 style= "margin-top: 1em;">Enter a value to convert to(or from) words</h3>
          <p id= " ">Use the "Demo" button for some examples.</p>
          <p>
          <textarea rows= "2" cols= "40" id= "strum_in"></textarea><br>
          <button id= "toWordsBtn" type= "button" style= "margin-left: 1em;">Convert</button>
          <button type= "button" id= "demoWordsBtn">Demo</button>
          <button id= "clearWordsBtn" type= "button">Clear</button>
          </p>
          <div id= "numword_div"></div>
          </div>
          </body>
          </html>
          

          【讨论】:

            【解决方案6】:

            我喜欢这样的问题,这是我对 PHP 的看法。我想让它尽可能紧凑,如果你想使用thousandthsmillionths,它很容易扩展。

            我不得不添加+ 0 来处理尾随+ 的可能性,这可行,但我不喜欢它的外观。如果需要过滤eval() 之前的字符,我会引入一些正则表达式并去掉\+$

            $find_replace = array(
                array('hundred', 'thousand', 'million', 'billion'),
                array('* 1e2 +', '* 1e3 +', '* 1e6 +', '* 1e9 +')
            );
            
            function words_to_number($input) {
                global $find_replace;
                $equation = str_replace($find_replace[0], $find_replace[1], $input) . ' + 0';
                $eval_result = eval('$result = ' . $equation . ';');
                return $eval_result === false ? $eval_result : $result;
            }
            
            $words = '3 million 240 thousand 7 hundred 54';
            $number = words_to_number($words);
            echo $words . ($number === false ? ' error!' : " == $number") . "\n";
            // 3 million 240 thousand 7 hundred 54 == 3240754
            
            $words = '5 thousand';
            $number = words_to_number($words);
            echo $words . ($number === false ? ' error!' : " == $number") . "\n";
            // 5 thousand == 5000
            

            【讨论】:

              猜你喜欢
              • 2010-11-04
              • 1970-01-01
              • 1970-01-01
              • 2016-07-02
              • 2018-02-22
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2017-10-07
              相关资源
              最近更新 更多