This example was written to convert numbers to words, but you can convert words to numbers in many cases- as long as the word input matches what would be output from the number to words calculation.
You are welcome to take what you can use and discard the rest.
<!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>