2014-01-13 8 views
5

Ich habe versucht, eine Zeichenfolge zu nehmen und gibt dann eine Zeichenfolge mit den Zahlen 1 bis 10 mit dem Wort für diese Zahlen ersetzt. Zum Beispiel:Ersetzen Sie Dezimalzahlen 1 bis 10 mit Namen ("eins", "zwei" ..)

Ich gewann 7 der 10 Spiele und erhielt 30 Dollar.

sollte geworden:

I gewann sieben der zehn Spiele und erhielt 30 Dollar.

Also tat ich dies:

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)); 

Und das Ergebnis ist folgendes:

ich gewann sieben der one0 Spiele und erhielt three0 Dollar.

Also versuchte ich einen Brute-Force-Weg, die ich bin sicher, mit regulären Ausdrücken oder eleganter String-Manipulation verbessert werden könnte:

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; 
    } 

} 

Gibt es einen besseren Weg? Besonders interessiert an Regex-Vorschlägen.

+2

Dies scheint ein ziemlich einfacher Aufruf von String.replaceAll() würde ausreichen. Stellen Sie sicher, dass Sie mit 10 beginnen, um das Problem von "one0" zu vermeiden. –

+0

Sie könnten versuchen, '10' an die Vorderseite des Arrays zu verschieben, so dass es vor' 1' ausgewertet wird. Aber es gibt wahrscheinlich eine richtigere Änderung. – crush

+3

@KevinWorkman Das OP muss auch damit umgehen, dass die "3" in "30" durch "drei" ersetzt wird. – GriffeyDog

Antwort

10

Dieser Ansatz verwendet reguläre Ausdrücke, die Ziel Ziffer von Nicht-Ziffern (oder den Anfang oder das Ende Zeichen) umgeben entsprechen:

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); 

Diese Drucke:

ich gewann sieben der zehn Spiele und erhielt 30 Dollar.

Erfüllt auch, wenn die Nummer das erste oder letzte Wort im Satz ist. Zum Beispiel:

9 Katzen eingeschaltet 100 anderen und tötete 10

übersetzt richtig

neun Katzen auf 100 andere drehte sich um und tötete zehn

+0

Bedeckt es diesen Fall: Meine Lieblingszahl ist 7, aber ich mag auch 5. – BobbyD17

+0

@ BobbyD17 Ein schneller Test schlägt ja vor. Was hat Sie vermuten lassen, dass es nicht möglich ist? –

+0

Es war einer der Kommentare unter meiner Antwort. Ich habe nur dafür gesorgt, dass du nachgesehen hast. Ich habe das Muster nie so benutzt wie du, und ich war mir nicht ganz sicher, wie es funktionierte. – BobbyD17

1

Bevor Sie eine beliebige Zahl durch ein Wort ersetzen, müssen Sie prüfen, ob der Nummer keine andere Nummer vorangestellt oder vorangestellt ist. Dies ist wahrscheinlich der einzige Weg um sicher zu sein, dass es nicht Teil einer größeren Anzahl ist. Sie ersetzen also nicht "30" durch "three0" und so weiter. Dies wird es ermöglichen, "30" oder "30" zu sein. oder "30" oder ein anderes Satzzeichen. Also muss der Check sicherstellen, dass es nicht 0-9 ist.

+1

Sie müssten auch den Fall behandeln, bei dem auf die Zahl ein Punkt und kein Leerzeichen folgt. – GriffeyDog

+0

guter Punkt. Vielleicht müssen Sie zuerst überprüfen, dass auf jede Phrase keine Zahl folgt. Bevor Sie etwas ersetzen, stellen Sie sicher, dass das nächste Zeichen keine Zahl ist. Hinzufügen als Bearbeitung – BobbyD17

+0

Bei HTML funktioniert das möglicherweise, weil Leerzeichen reduziert sind. In allen anderen Fällen ist dies eine schlechte Lösung. –

Verwandte Themen