1

I want to change all numbers ranging from 1-9 to their spelled out equivalents in a string, such as changing all 1 to one, 3 to three, etc.

I tried string.replace() like this:

let string = "I have 3 cats";
string = string.replace(/3/g, "three");

This works fine for the above string, but it also changes 33 to threethree which is not what I want. I also tried

string = string.replaceAll(" 3 ", "three);

But this resulted in strings beginning with a number like "5 dollars is a lot of money" being overlooked. What should I do?

Edit: I am sorry if I didn't make my question clear. I wanted numbers higher than 1-9 like 33 to remain as 33, and only change the 9 numbers.

Yoshi
  • 11
  • 2
  • Do you have any restrictions for the input string? It is difficult to treat all the options unless you can limit the entry numbers from the user to 1-9. – Filip Seman Jan 31 '21 at 10:07
  • I believe if you want to target all numbers, you need a more complex function since you're only handling from 0-9 .. So you can do this, for every number, if it contains only 1 character, use your current function, then for numbers with 2 characters, convert the first character to the equivalent, for example: "21" so first character becomes "twenty" then final character "one" then if second character is 0, ignore second character, so it becomes only "twenty", I believe you get the pattern here – Cypherjac Jan 31 '21 at 10:09
  • Does this answer your question? [Convert digits into words with JavaScript](https://stackoverflow.com/questions/14766951/convert-digits-into-words-with-javascript) – Filip Seman Jan 31 '21 at 10:11
  • I do not want to have any restrictions on the string, so ideally the entry numbers will not be limited from 1-9. Also, the link provided unfortunately does not, because I am only looking to convert numbers from 1-9 to words, not anything higher. – Yoshi Jan 31 '21 at 10:14
  • @Yoshi you can modify any answer to transform only `1-9` range – Filip Seman Jan 31 '21 at 10:28
  • Compelling first question! Welcome to StackOverflow! – Dexygen Jan 31 '21 at 10:40
  • Ah I see, thank you so much! – Yoshi Jan 31 '21 at 12:21

4 Answers4

2

do you want to replace 3 but not 33? you can use regex boundary \b or whole word

numbers = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine'];
var s = "I have 3 cats with 33 lives";
result = s.replace(/\b\d\b/g, m => numbers[m])

console.log(result)
uingtea
  • 6,002
  • 2
  • 26
  • 40
  • This works great! For my understanding, can I ask how the variable m is used in the code? I am not too sure how m and the arrow function helps the function do what it does. – Yoshi Jan 31 '21 at 12:34
  • in `.replace()` we can change static/string replacement with function, `m` is function parameter, the arrow function above is simplified version of `function(m) { return numbers[m] }` – uingtea Jan 31 '21 at 14:22
1

let string = "I have 3 cats. 55 dollars is a lot of money. 2 dollar is fine";
let numbersList = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine'];

string = string.split(" ").map(val => numbersList[val] || val).join(" ");

console.log(string);
aRvi
  • 2,203
  • 1
  • 14
  • 30
  • Thank you very much. As someone relatively new to javascript, could you explain how the solution works briefly? I am not sure how to understand this line of code: `string = string.split(" ").map(val => numbersList[val] || val).join(" ");` – Yoshi Jan 31 '21 at 10:21
  • first I converted the sentence to words and compared each word if it is a number then pick from `numbersList` or else use the existing word and then convert it back to sentence – aRvi Jan 31 '21 at 10:23
  • Aah, that makes it a lot clearer. I think that helps a lot. – Yoshi Jan 31 '21 at 10:24
  • Sorry one last question, how does the code recognize val when it wasn't defined? I think I am misunderstanding something here. – Yoshi Jan 31 '21 at 10:29
  • it is a property of the map function – aRvi Jan 31 '21 at 10:31
0

You could take a function for replacing and search for a digit and replace it with a value.

The implemented approach works up to 999.

function wordify(n) {
    n = +n;
    let word = [],
        numbers = { 1: 'one', 2: 'two', 3: 'three', 4: 'four', 5: 'five', 6: 'six', 7: 'seven', 8: 'eight', 9: 'nine', 10: 'ten', 11: 'eleven', 12: 'twelve', t3: 'thir', t5: 'fif', t8: 'eigh', 20: 'twenty' },
        hundreds = 0 | (n % 1000) / 100,
        tens = 0 | (n % 100) / 10,
        ones = n % 10;

    if (n === 0) {
        return 'zero';
    }
    if (hundreds) {
        word.push(numbers[hundreds] + ' hundred');
    }
    if (tens === 0) {
        word.push(numbers[ones]);
    } else if (tens === 1) {
        word.push(numbers['1' + ones] || (numbers['t' + ones] || numbers[ones]) + 'teen');
    } else {
        word.push(numbers[tens + '0'] || (numbers['t' + tens] || numbers[tens]) + 'ty');
        if (numbers[ones]) {
            word.push(numbers[ones]);
        }
    }
    return word.join(' ');
}

let string = "I have 3 cats. 55 dollars is a lot of money."

string = string.replace(/\d+/g, wordify);

console.log(string);
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
0

You need to use a regular expression to identify numbers of variable length & use convert each matched number to its English word equivalent using function parameter.the expression used by you only search for single occurrence of 3. use the following code below:

    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',
    100: 'hundred',
    1000: 'thousand',
  }
  
  const numberValues = Object.keys(numberText)
    .map((val) => Number(val))
    .sort((a, b) => b - a)
  
  const convertNumberToEnglishText = (n) => {
    if (n === 0) return 'zero'
    if (n < 0) return 'negative ' + convertNumberToEnglishText(-n)
  
    let num = n
    let text = ''
  
    for (const numberValue of numberValues) {
      const count = Math.trunc(num / numberValue)
  
      if (count < 1) continue
  
      if (numberValue >= 100) text += convertNumberToEnglishText(count) + ' '
  
      text += numberText[numberValue] + ' '
      num -= count * numberValue
    }
  
    if (num !== 0) throw Error('Something went wrong!')
  
    return text.trim()
  }

let input ="I have 3 cats and 567 dogs";

// console.log(input.replace(/\d+/g,'T'));
console.log(input.replace(/\d+/g, (match) => { 
    return convertNumberToEnglishText(match)
}));
Sanath.usk
  • 84
  • 5