0

The following portion of Java code scans the string given to find sequence of numbers, either individual or grouped. But the problem I find is that I need to write the name of the numbers as individual and not as grouped. That is, if the string has "Hello78, my name is number07 and not number1", instead of printing as "Seventy Eight", how can I get it to be "Seven Eight"?

    Pattern patternString = Pattern.compile("\\d+");
    String inputText = "32h28ello12'34' this is a test89 87";
    Matcher findNumber = patternString.matcher(inputText);
    Scanner findText = new Scanner(inputText);
    findText.useDelimiter("[^\\p{Alnum},\\.-]");
    int counter = 0;
    List<String> list = new ArrayList<>();

    while (findNumber.find()) {
        list.add(findNumber.group());

        System.out.println(findNumber.group(0));
    }

So, this is an example of the output just to guide myself:

32
28
12
34
89
87
-----------------------------------------------
LIST: [32, 28, 12, 34, 89, 87]
32h28ello12'34' this is a test89 87
-----------------------------------------------

I am using the line below to continue testing and to replace the number for the text, but then I realize that I need to replace the whole number in that position. That is, if it is 30, then the text is "Three Zero" and not "Three" alone or "Zero" alone.

numString = inputText.replace(Character.toString(inputText.charAt(atPos)), one);

Some of the ideas I have had are for example, putting each output number in another variable, the read it back, then split it (each) and writing the number's name, but I can't figure out how to do it. Any idea will be appreciated.

4
  • 2
    You should iterate the string char by char, and if char value lies between 49 & 57, use a switch-case statement to print char value as string! Commented Sep 7, 2017 at 3:09
  • I was thinking something like that, but it means to write a lot of code (just looking for alternatives). Not sure about the use of switch-case. Do you have a little example for this case? Commented Sep 7, 2017 at 3:17
  • 1
    Scan though the characters of your string; use Character.isDigit(ch) to test each one to see if it's a digit. If not, just append it to your result string. If it is a digit, use Character.digit(ch,10) to obtain its numeric value, then use that value to index an array of Strings containing the digit names and append that text to your result. Commented Sep 7, 2017 at 3:25
  • 1
    Why not having a Map<Character, String> that contains the 10 digits character as key and there string counterpart as value. Then just traverse the string and replace the digits with the value associated in map?? Commented Sep 7, 2017 at 3:32

3 Answers 3

2

If you are expecting "HelloSeven Eight, my name..." as your out put then you can use this:

    String[] numberTexts = {"Zero", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine"};
    StringBuilder builder = new StringBuilder();
    String inputText = "32h28ello12'34' this is a test89 87";

    for (int i=0; i < inputText.length(); i++) {
        char c = inputText.charAt(i);
        if (Character.isDigit(c)) {
            String numberText = numberTexts[Character.getNumericValue(c)];
            builder.append(numberText);
            // append space if next character is a digit
            if (i < inputText.length() - 1 && Character.isDigit(inputText.charAt(i+1))){
                builder.append(" ");
            }
        } else {
            builder.append(c);
        }
    }

    System.out.println(builder.toString());

Here the inputText is iterated for all characters and numbers are replaced with their text. If next character is a number then a space character is appended.

Sign up to request clarification or add additional context in comments.

Comments

1

Use a StringBuilder instead of constantly creating new intermediate strings.

StringBuilder sb = new StringBuilder();
for ( char c : inputText ) {
  switch (c) {
    case '0':
       sb.append("zero ");
       break;
    // similar for '1 thru '9'
    default:
       sb.append(c);
       break;
  }
}
String output = sb.toString();

2 Comments

Won't this have an extra space when there is a single digit ?
Use StringJoiner instead, same benefit and you won't need to trim the resulting text
1

Using Map<Character, String>:

    Map<Character, String> map = new HashMap<>();
    map.put('0', "zero");
    map.put('1', "one");
    map.put('2', "two");
    map.put('3', "three");
    map.put('4', "four");
    map.put('5', "five");
    map.put('6', "six");
    map.put('7', "seven");
    map.put('8', "eight");
    map.put('9', "nine");

    String inputString = "Hello78, my name is number07 and not number1";

    StringBuilder builder = new StringBuilder();
    for (int i = 0; i < inputString.length(); i++) {
        builder.append(map.getOrDefault(inputString.charAt(i), String.valueOf(inputString.charAt(i))));
    }

    String outputString = builder.toString();

EDIT: Using String[] as suggested by @Kevin Anderson in comments (this looks much better):

        String[] array = {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"};

        String inputString = "Hello78, my name is number07 and not number1";

        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < inputString.length(); i++) {
            if (Character.isDigit(inputString.charAt(i))) {
                builder.append(array[Character.digit(inputString.charAt(i), 10)]);
            } else {
                builder.append(inputString.charAt(i));
            }
        }

        String outputString = builder.toString();

outputString will have Helloseveneight, my name is numberzeroseven and not numberone in either of the above solution.

You need to handle spaces in the beginning/end of words.

1 Comment

I think this may work! Thanks so much, also to the others. More answers are welcome for further reference.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.