2013-05-19 10 views
5

Ich mag Wortzählimpuls von einem String erhalten. So einfach ist das. Der Haken ist, dass die Zeichenfolge in einer unvorhersehbaren Sprache sein kann.Get Wort aus einem String in Unicode (in jeder Sprache) zählt

Also, ich brauche eine Funktion der Signatur int getWordCount(String) mit der folgenden Beispielausgabe -

getWordCount("供应商代发发货") => 7 
getWordCount("This is a sentence") => 4 

Jede Hilfe, wie geschätzt fortfahren würde :)

+0

Im chinesischen (?) Text ist ein Trennzeichen zwischen den Wörtern? –

+0

Nein, es gibt kein Trennzeichen. Ich habe die genauen Zeichenfolgen kopiert. – jaibatrik

+0

In diesem Fall würde ich versuchen, die Sprache zu finden, auf der Unicode-Runen in der Zeichenfolge verwendet werden.Verwenden Sie dann diese Informationen, um festzustellen, wie die Zeichenfolge analysiert werden soll. –

Antwort

5

Der Begriff "Wort" mag trivial oder komplex sein. Hier ist Apache Stanbol Toolkit:

Wort Tokenisierung: Der Nachweis von einzelnen Worten ist erforderlich durch den Stanbol Enhancer Text zu verarbeiten. Während dies für die meisten Sprachen trivial ist, ist es eine ziemlich komplexe Aufgabe für einige östliche Sprachen, z.B. Chinesisch, Japanisch, Koreanisch. Wenn nicht anders konfiguriert, verwendet Stanbol Leerzeichen, um Wörter zu tokenisieren. So

wenn der Begriff des Wortes sprachlichen, anstatt syntaktische, sollten Sie ein verwenden NLP toolkit

Meine bevorzugte Java-Lösung ist Apache's Open NLP

HINWEIS: Ich habe verwendet http://www.mdbg.net/chindict/chindict.php?page=worddict Ihr Beispiel tokenize . Es bedeutet, dass es 4 Wörter gibt, nicht sieben.Ich habe geschnitten und geklebt (eher fragmentiert):

Originaltext Simplified Pinyin Englisch Definition ein neues Wort in das Wörterbuch Traditionelle HSK hinzufügen 供应 商 供应 商 gōng ying shang

Lieferant

供應 商 代
代 dài

ersetzen/im Namen anderer zu handeln/ersetzen/Generation/Dynastie/Alter/Zeit/(historische) Ära/(geologischen) eon


发 fā

auszusenden/zeigen (man das Gefühl)/zur Ausgabe von/zu entwickeln/Klassifizierer für Schüssen (Runden)

發 HSK 4

发 fà

Haare/Taiwan pr. [Fa3]

髮 发货
发货 fā huò

zum Versand/Waren

發貨

Diese ersten drei Zeichen auszusenden erscheinen eine einzige zu bilden Wort.

+0

Danke für Ihre Hilfe. Ich denke, Ihre Herangehensweise ist sehr logisch. Ich werde jetzt versuchen, ein paar Toolkits zu finden, um zu sehen, wie ich das herausfinden kann. – jaibatrik

+0

Gut. Vielleicht möchten Sie mit einem PartOfSpeech Tagger beginnen, der Substantive, Verben usw. erkennt. Und es gibt mit ziemlicher Sicherheit einige Online-Dienste, die Ihnen helfen, Ihr Problem zu erforschen. Und Ihr Gesamtproblem ist wahrscheinlich komplexer als das bloße Finden von Wörtern. –

+0

Kennen Sie ein einfaches Toolkit/Service dafür? Kann ein guter Wort Tokenizer sein? – jaibatrik

1

englische Version

Für die englische Version kann man mit einem eher einfachen Regex machen. Vielleicht habe ich einige benutzerdefinierte Separatoren verfehlt aber:

public static int getWordCount(String str) { 
    return str.split("[\\s,;-]+").length; 
} 

Regex Erklärung:

Split wenn [] jeder in der Gruppe finden:

[ 
\\s Any whitespace character or 
, A comma 
; or a semi-colon 
] 
+ Followed by any patterns in the group any number of times 

chinesische Version

Für die chinesische Version, müssen Sie identifizieren, was die Separato rs sind. Wenn Sie den Unicode-Zeichencode der chinesischen Trennzeichen erhalten und sie dem obigen Regex hinzufügen, erhalten Sie die gewünschten Ergebnisse.

Tests

System.out.println(getWordCount("This is a sentence"));// 4 
System.out.println(getWordCount("This is a sentence")); // 4 
System.out.println(getWordCount("This is a  ,,sentence")); // 4 
+0

Danke für Ihren Vorschlag. Werde es versuchen. – jaibatrik

2

Wenn wir davon ausgehen, dass jede Sprache hat eine (oder mehrere) Wortseparator, und Sie können regex für diejenigen Separator bauen, dann kann das Problem wie folgt gelöst werden:

public String separatorForLanguage(char unicodeChar){ 
     // Find out in which language unicodeChar falls 
     return ""; // return regex of separator of that language 
    } 

    public int wordCount(String sentance){ 
     char unicodeChar = sentance.charAt(0); 
     String separator = separatorForLanguage(unicodeChar); 

     int count = sentance.split(separator).length; 
     if (separator.isEmpty()) { 
      count--; 
     } 

     return count; 
    } 
+0

Danke für die Antwort. Eigentlich hat der chinesisch/japanische Text kein Trennzeichen und das ist das Problem. – jaibatrik

+0

@jaibatrik: dann ist das Trennzeichen eine leere Zeichenfolge, nehme ich an. – Mohayemin

+0

Ja, das scheint logisch. Danke für den gut präparierten Pseudocode. Wertschätzung und Up-Vote! – jaibatrik

5

Die Standard-API bietet die BreakIterator Für diese Art der Grenzanalyse wird die Beispielzeichenfolge jedoch nicht durch die Oracle Java 7-Gebietsschemaunterstützung unterbrochen.

Wenn ich die ICU4J v51.1 BreakIterator verwendet, brach es die Probe in [供应, 商代, 发, 发, 货].

// import com.ibm.icu.text.BreakIterator; 
String sentence = "\u4f9b\u5e94\u5546\u4ee3\u53d1\u53d1\u8d27"; 
BreakIterator iterator = BreakIterator.getWordInstance(Locale.CHINESE); 
iterator.setText(sentence); 

List<String> words = new ArrayList<>(); 
int start = iterator.first(); 
int end = iterator.next(); 
while (end != BreakIterator.DONE) { 
    words.add(sentence.substring(start, end)); 
    start = end; 
    end = iterator.next(); 
} 
System.out.println(words); 

Hinweis: Früher habe ich Google zu erraten, Übersetzen, dass "供应 商代 发 发货" Chinese war. Offensichtlich spreche ich die Sprache nicht, kann also die Korrektheit der Ausgabe nicht kommentieren.

+0

Danke für das Teilen. Up-Voting Sie auch! – jaibatrik

2

Hier Schnipsel in Java

public static int getWordCount(String string) 
{ 
    Pattern pattern = Pattern.compile("[\\w']+|[\\u3400-\\u4DB5\\u4E00-\\u9FCC]"); 
    Matcher matcher = pattern.matcher(string); 
    int count = 0; 
    while(matcher.find()) 
     count++; 
    return count;         
} 

Beispiel

//count is 5 
int wordCount = getWordCount("this is popcorny's 電腦");