2016-04-29 13 views
1

Ich suche nach Lösung des Problems. Ich muss eine Art Methode erstellen, die Liste der Wörter und nur Wörter erstellt, für jeden gegebenen Text, einschließlich nicht-Englisch Buchstaben und Sonderzeichen. Ich suchte viel und ich las Dokumentation here, aber irgendetwas davon funktioniert nicht perfekt für mich. Einer der besten ist diese:Teilen ganzen Text in Worte mit einer Regex

String line = " W metal, w liczbę, w trupie ciało, -" 
String[] words = line.split("\\P{javaLetter}+"); 
    for (int i = 0; i < words.length; i++) { 
     if (!words[i].equals("")) { // I don't want to check everytime 
      anotherList.add(word[i].toLowerCase()) 
     } 
    } 
} 

aber das Ergebnis ist:

["", "W", "metal", "w", "liczbę", "w", "trupie", "ciało"] 

Diese Leerzeichen am Anfang von String bricht mir das regex nach unten. Welches ist die richtige Regex für Wörter in einer beliebigen Sprache mit lateinischen Alphabet (achten Sie nicht auf Apostrophe in englischen Wörtern)?

+1

haben Sie versucht line.split (“„)? es macht Sinn, auf Leerzeichen zu splitten, um die Wörter in einem Satz zu erhalten. Regex ist großartig, aber auch sehr flink. –

+0

Drucken Sie Wörter oder eine andere Liste? –

+0

@tobias_k offensichtlich Wörter, weil anotherList nicht die leere Zeichenfolge, die im ersten Index seines Ergebnisses existiert. –

Antwort

2

können Sie den umgekehrten Weg verwenden - Matching:

List<String> words = new ArrayList<>(); 
String line = " W metal, w liczbę, w trupie ciało, -"; 
Matcher m = Pattern.compile("\\p{L}+").matcher(line); 
while (m.find()) { 
    words.add(m.group()); 
} 
System.out.println(words); // => [W, metal, w, liczbę, w, trupie, ciało] 

die IDEONE demo See. Die \\p{L}+ entspricht 1+ beliebigen Unicode-Buchstaben.

Es gibt einen Weg Splitting Ansatz zu verwenden, aber wir müssen zuerst die Eingabezeichenfolge vorverarbeitet:

String line = " W metal, w liczbę, w trupie ciało, -"; 
String[] words = line.replaceFirst("^\\P{L}+", "").split("\\P{L}+"); 
System.out.println(Arrays.toString(words)); 

Siehe another IDEONE demo

Die .replaceFirst("^\\P{L}+", "") werden alle Nicht-Buchstaben-Symbole von Anfang an entfernen der String, so dass keine leeren Elemente in der Split-Array.

+0

Ich denke, das ist der bessere Ansatz. Es ist eine Schande, dass Java keine einfachere Methode hat, um alle Matches zu bekommen. –

+1

Die beste Lösung. Vielen Dank. Ich muss Split nicht verwenden, aber ich dachte, es ist der einfachste Weg, dies zu tun. – qwaler

0

Angenommen, Sie möchten, dass das Ergebnis words dasselbe ist wie anotherList, aber ohne Nachbearbeitung der Ergebnisse in einer Schleife. Wie wäre es mit einer Vorverarbeitung?

String line = " W metal, w liczbę, w trupie ciało, -"; 
String[] words = line.trim().toLowerCase().split("\\P{javaLetter}+"); 
System.out.println(Arrays.toString(words)); 

Ergebnis: [w, metal, w, liczbę, w, trupie, ciało]

+0

Und wenn es ein Nicht-Buchstaben/Nicht-Leerzeichen am Anfang ist? :) –

+0

@ WiktorStribiżew Nun, ich denke, in diesem Fall wird es noch einige '' 'im Ergebnis geben ...: -/ –

0

Zuerst das einzelne obere Zitat in seinen Variationen, die ich hinzugefügt habe. Dann alle Buchstaben und Null-Breite Akzente, die mit den Buchstaben kombinieren.

String[] rawWords = line.trim().split("(?U)[^\\p{L}\\p{M}'\u0060\u00b4\u2017]"); 

Suchen Sie im Javadoc von Muster für die Regex.

Dies verhindert kein vorangestelltes leeres Wort, wenn die Zeile nicht mit einem Wort beginnt. Das könnte auch ersetzt werden, aber eine Überprüfung würde ausreichen.

Ein anderes Problem ist, dass jedes einzelne Zitat gedacht wird, um ein Teil eines Wortes zu sein. Dies kann getan werden, indem alle führenden und hinteren Folgen von Anführungszeichen von Wörtern entfernt werden.

Ich würde nicht versuchen, eine einzige Regex zu machen, obwohl das für das Zitat Problem sicherlich möglich ist.

Eine Vereinfachung ist die Verwendung der Unicode-Textnormalisierung. "ŝ" könnte ein char \u0150 oder zwei Zeichen c plus eine Nullbreite ^ sein. Dies kann mit der Klasse java.text.Normalizer erfolgen. Dann könnte \\p{M} nicht mehr benötigt werden, wenn Sie das kombinierte Formular verwenden. Auch alle diese einfachen Anführungszeichen könnten durch das Apostroph ' ersetzt werden.

(für die Verarbeitung natürlicher Sprache JNLP könnte von Interesse sein.)

Verwandte Themen