Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replace decimals 1 to 10 with name ("one", "two"..)

Tags:

java

string

regex

I was trying to take a string and then returns a string with the numbers 1 to 10 replaced with the word for those numbers. For example:

I won 7 of the 10 games and received 30 dollars.

should become:

I won seven of the ten games and received 30 dollars.

So I did this:

import org.apache.commons.lang3.StringUtils;

String[] numbers = new String[] {"1", "2", "3","4","5","6","7","8","9","10"};
String[] words   = new String[]{"one", "two", "three","four","five","six",
    "seven","eight","nine","ten"};
System.out.print(StringUtils.replaceEach(phrase, numbers, words));

And the result is this:

I won seven of the one0 games and received three0 dollars.

So I tried a brute force way which I'm sure could be improved with regular expressions or more elegant string manipulation:

public class StringReplace {

  public static void main(String[] args) {
    String phrase = "I won 7 of the 10 games and received 30 dollars.";
    String[] sentenceWords = phrase.split(" ");
    StringBuilder sb = new StringBuilder();
    for (String s: sentenceWords) { 
      if (isNumeric(s)) { 
        sb.append(switchOutText(s));
      }

      else { 
        sb.append(s);
      }
      sb.append(" ");

    }
    System.out.print(sb.toString());
  }

  public static String switchOutText(String s) { 
    if (s.equals("1"))
      return "one";
    else if (s.equals("2"))
      return "two";
    else if (s.equals("3"))
      return "three";
    else if (s.equals("4"))
      return "four";
    else if (s.equals("5"))
      return "fivee";
    else if (s.equals("6"))
      return "six";
    else if (s.equals("7"))
      return "seven";
    else if (s.equals("8"))
      return "eight";
    else if (s.equals("9"))
      return "nine";        
    else if (s.equals("10"))
      return "ten";
    else
      return s;        
  }

  public static boolean isNumeric(String s) { 
    try { 
      int i = Integer.parseInt(s);
    }
    catch(NumberFormatException nfe) { 
      return false;
    }
    return true;
  }

}

Isn't there a better way? Especially interested in regex suggestions.

like image 381
Kristy Welsh Avatar asked Jan 13 '14 14:01

Kristy Welsh


2 Answers

This approach uses regular expressions to match the target digit surrounded by non-digits (or the start or end character):

String[] words = { "one", "two", "three", "four", "five", "six", "seven",
    "eight", "nine", "ten" };
String phrase = "I won 7 of the 10 games and received 30 dollars.";

for (int i = 1; i <= 10; i++) {
  String pattern = "(^|\\D)" + i + "(\\D|$)";
  phrase = phrase.replaceAll(pattern, "$1" + words[i - 1] + "$2");
}

System.out.println(phrase);

This prints:

I won seven of the ten games and received 30 dollars.

It also copes if the number is the first or last word in the sentence. For instance:

9 cats turned on 100 others and killed 10

correctly translates to

nine cats turned on 100 others and killed ten

like image 114
Duncan Jones Avatar answered Sep 21 '22 01:09

Duncan Jones


Before replacing any number with a word, you need to check that the number is not followed or preceeded by another number. This is probably the only way to be sure that it is not part of a bigger number. So you won't be replacing "30" with "three0" and so on. This will allow it to be "30 " or "30." or "30," or any other punctuation mark. So, the check will have to make sure it is not 0-9.

like image 37
BobbyD17 Avatar answered Sep 23 '22 01:09

BobbyD17