2009-04-15 3 views
0

Ich versuche gerade, eine Textdatei zu filtern, die Wörter enthält, die durch ein "-" getrennt sind. Ich möchte die Wörter zählen.Verwendung der Delimiter-Funktion vom Scanner für "abc-def"

Das Problem, das einfach auftritt, ist: Wörter, die ein "-" enthalten, werden getrennt und als zwei Wörter gezählt. Also einfach mit \ - zu entkommen, ist nicht die Lösung der Wahl.

Wie kann ich den Begrenzerausdruck ändern, so dass Wörter wie "foo-bar" bleiben, aber das "-" allein wird herausgefiltert und ignoriert?

Danke;)

+0

Dies ist nicht klar, können Sie einige Beispiele von was Sie wollen und was Sie nicht wollen, bitte? – chburd

+0

@chburd: Ich denke, er will "eins zwei drei - vier" drei Worte sein. –

Antwort

1

OK, ich vermute Ihre Frage hier: Sie meinen, dass Sie eine Textdatei mit einigen "echten" Prosa, d. H. Sätze, die eigentlich Sinn machen, durch Satzzeichen und dergleichen usw. getrennt sind, oder?

Beispiel:

Diese Situation verbessert wird - soweit wir das beurteilen können - durch die Tatsache, dass unsere größt Verbündete, die Vorgons, weiterhin ihre Poetry Slam Wettbewerbe zu halten; der Feind hat wenig Anreiz, das zu stören, sogar mit ihren Mute-O-Matic-Geräten.

Also, was Sie als Trennzeichen brauchen, ist etwas, das entweder eine beliebige Menge von Leerzeichen und/oder Zeichensetzung (die Sie bereits mit dem regulären Ausdruck abgedeckt haben Sie gezeigt) oder ein Bindestrich, die von mindestens einem Leerzeichen umgeben ist auf jeder Seite. Das Regex-Zeichen für "oder" ist "|". Es gibt eine Verknüpfung für die Whitespace-Zeichenklasse (Leerzeichen, Tabulatoren und Zeilenumbrüche) in vielen Regex-Implementierungen: "\ s".

"[.,:;()?!\"\s]+|\s+-\s+" 
0

Dies ist nicht sehr einfach. Eine Sache, die Sie versuchen sollten, wäre {current-delimeter-chars} {null-oder-mehr-Bindestriche} {null-oder-mehr-aktuell-delimeter-chars-or-hyphen}.

Es könnte einfacher sein, nur Worte durch den Scanner zurück ignoriert vollständig aus Bindestrichen

0

Wenn möglich versuchen, die vordefinierten Klassen ... zu verwenden, die aus macht den Regex viel einfacher zu lesen. Siehe java.util.regex.Pattern für Optionen.

Vielleicht ist es das, was Sie suchen:

string.split("\\s+(\\W*\\s)?" 

Liest: Match 1 oder mehr Leerzeichen Zeichen gegebenenfalls gefolgt von null oder mehr Nicht-Wortzeichen und ein Leerzeichen.

+0

Ich sollte auch darauf hinweisen, dass Regex-Muster doppelt entflochten werden müssen, sonst wird der Compiler beschweren, dass \ foo kein gültiges String-Zeichen ist. – CurtainDog

0
Scanner scanner = new Scanner("one two2 - (three) four-five - ,....|"); 
scanner.useDelimiter("(\\B+-\\B+|[.,:;()?!\" \t|])+"); 

while (scanner.hasNext()) { 
    System.out.println(scanner.next("\\w+(-\\w+)*")); 
} 

NB

die nächste (String) Methode behauptet, dass Sie nur Worte, da die ursprüngliche useDelimiter() -Methode Misses erhalten "|" "| \ N \ r \ n" als Zeilenabschluss

NB

Sie haben den regulären Ausdruck verwendet. Die JavaDocs für java.util.regex.Muster zeigen andere mögliche Linie Terminator, so eine vollständigere Kontrolle würde verwendet den Ausdruck "\ r \ n | [\ r \ n \ u2028 \ u2029 \ u0085]"

+0

\ B ist eine Assertion mit der Breite null; es stimmt mit einer Position überein, die keine Wortgrenze ist. Es verbraucht keine Zeichen, daher macht es keinen Sinn, ein "+" oder einen anderen Quantifizierer hinzuzufügen. Java ignoriert nur den Quantifizierer, aber einige andere Regex-Varianten behandeln es als Syntaxfehler. –

+0

Außerdem verwendet das OP nicht "\ r \ n | \ n". Line-Separatoren interessiert ihn überhaupt nicht. Er passt nur die häufigsten Leerzeichen zusammen mit den Interpunktionszeichen in der Zeichenklasse an (aber er sollte "\ s" verwenden, wie @Svante es getan hat). –

+0

benutzte er \ r \ n in GebrauchDelimiter(), übrigens danke für die erste Klärung! :) – dfa

0

Dies soll eine einfach genug: [^\\w-]\\W*|-\\W+

  • Aber natürlich, wenn es Prosa, und Sie wollen auszuschließen unterstreicht:
    [^\\p{Alnum}-]\\P{Alnum}*|-\\P{Alnum}+
  • oder wenn Sie erwarten, Numerik nicht:
    [^\\p{Alpha}-]\\P{Alpha}*|-\\P{Alpha}+

EDIT: Dies sind leichtere Formen. Denken Sie daran, dass die vollständige Lösung, die Bindestriche am Anfang und am Ende von Zeilen behandelt, diesem Muster folgen würde. (?:^|[^\\w-])\\W*|-(?:\\W+|$)