Unterschied Scanner und Matcher

Status
Nicht offen für weitere Antworten.

Andreas29

Bekanntes Mitglied
Hi Leute,

ich kämpfe gerade mit regulären Ausdrücken und den beiden Klassen Scanner und Matcher. Folgendes sehr einfaches Beispiel:
Mein String sieht so aus:
test temp
Mein Pattern ist:
temp

Folgender Code verwirrt mich:
Code:
public class ScannerTest {

    public static void main(String[] args) {
        Scanner scanner = new Scanner("test temp");
        Pattern pattern = Pattern.compile("temp");
        if (scanner.hasNext(pattern)) {
            System.out.println("gefunden");
            MatchResult matchResult2 = scanner.match();
            System.out.println(matchResult2.group());
        } else {
            System.out.println("doch nicht");
        }
        Matcher matcher = pattern.matcher("test temp");
        if (matcher == null || !matcher.find()) {
            System.out.println("nichts gefunden");
        } else {
            System.out.println("irgendwas wurde gefunden");
            MatchResult matchResult = matcher.toMatchResult();
            System.out.println(matchResult.group());
        }

    }
}
Wenn ich mein Pattern über die Scanner-Klasse verwende, bekomme ich als Ausgabe "doch nicht", sprich er hat nichts gefunden. Wenn ich den Matcher direkt anspreche, bekomme ich "irgendwas wurde gefunden" und "temp" als Ausgabe, sprich das Pattern wurde gefunden. Wo ist der Unterschied? Ich würde die Scanner Klasse sehr gerne verwenden, da ich ihr auch einen InputStream als Basis übergeben kann, was beim Matcher nicht der Fall ist, ich aber benötige, da die Datenmengen, die ich mit der regex durchsuchen möchte, durchaus größer werden können. Hat irgendwer eine Idee, warum der Scanner das Pattern nicht findet? Soweit ich das im Source von sun sehen konnte, verwenden die doch intern auch den Matcher, oder habe ich das falsch gelesen? Ich bin ein wenig verwirrt...

Danke für eure Hilfe und sonnige Grüße aus dem schönen Flensburg,
Andreas
 
hasNext() schaut sich das nächste Token an, das ist 'test' und passt nicht zu 'temp'

find() macht ganz was anders, durchsucht einen String beliebiger Länge nach dem Pattern,
wieso sollten diese Operationen das gleiche machen?
 
Das "hasNext" bezieht sich nur auf den Beginn des aktuellen Streams, also in deinem Fall wird getestet ob "test temp" mit "temp" beginnt (nein, tut es nicht).

Du könntest eine Schleife machen in der du immer das erste Zeichen des Scanners liest (und somit den Start des Scanners verschiebst), und dann nocheinmal testest.

Bei grösserem Input lohnt es sich vielleicht, einen hardcodierten Lexer zu verwenden - z.B. JFlex kann dir einen solchen generieren.
 
Hi,

erstmal danke für die Antworten!

Ich hatte hasNext() so verstanden, dass er den kompletten String durchsucht und mir sagt, ob der String noch einmal mein Pattern beinhaltet. Aber dies scheint dann wohl die find() methode zu machen. Wieder etwas gelernt. Tja, man kann alt werden wie ein Haus und lernt doch nicht aus.

So, die Antwort war ein bisschen schnell:
Und wie bekomme ich den Scanner dazu, so zu arbeiten, wie Matcher.find()? Gibt es da keine fertigen Methoden für?

Dank euch!

Grüße,
Andreas
 
ein Scanner ist dafür da, einen String von Anfang bis Ende zu durchlaufen,
er ist kein JFrame, kein Integer und auch kein Matcher,
wieso sollte er? 😉

dass du in einer Schleife token auslassen kannst, hat Beni ja schon geschrieben
 
Hi,

der Scanner durchläuft den String nur nicht so, wie ich es erwartet habe. Ich dachte, er durchläuft von vorne den String und gibt mir in seiner next Methode das nächste Token zurück, welches auf meine regex zutrifft, was er aber nicht tut. Und da war mein falsches Verständnis. Ich bräuchte also einen Matcher, der nicht auf String sondern auf InputStream Basis arbeitet. Die Idee mit der for-Schleife muss ich mir nochmal durch den Kopf gehen lassen.

Ich hatte halt simpel und einfach ein anderes Verhalten erwartet.

Grüße,
Andreas
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Zurück
Oben