2 Stimmen

Haskell: Begrenzung einer Zeichenkette durch ausgewählte Teilzeichenketten und Leerzeichen

Bin noch neu in Haskell, so entschuldigen, wenn es eine offensichtliche Antwort auf diese...

Ich möchte eine Funktion erstellen, die alle folgenden Listen von Strings aufteilt, d.h. [String]:

["int x = 1", "y := x + 123"]
["int   x=   1", "y:=   x+123"] 
["int x=1", "y:=x+123"] 

Alle in dieselbe Zeichenfolge von Zeichenfolgen, d. h. [[String]]:

[["int", "x", "=", "1"], ["y", ":=", "x", "+", "123"]]

Sie können verwenden map words.lines für die erste [Zeichenfolge].

Aber ich kenne keine wirklich saubere Methode, um auch die anderen zu berücksichtigen - wo Sie die verschiedenen Unterzeichenfolgen verwenden würden "=" , ":=" , "+" usw., um die Hauptkette zu unterbrechen.

Danke, dass Sie sich die Zeit genommen haben, mich über Haskell aufzuklären :-)

7voto

luqui Punkte 58358

Prelude wird mit einer wenig bekannten, praktischen Funktion namens lex der ein Lexer für Haskell-Ausdrücke ist. Diese entsprechen der Form, die Sie benötigen.

lex :: String -> [(String,String)]

Aber was für ein seltsamer Typ! Die Liste ist dazu da, um mit einem Standard-Parser zusammenzuarbeiten, aber ich bin mir ziemlich sicher lex gibt immer entweder 1 oder 0 Elemente zurück (0 bedeutet, dass das Parsen fehlgeschlagen ist). Das Tupel ist (token-lexed, rest-of-input) also lex zieht nur eine Marke ab. Eine einfache Möglichkeit, eine ganze Zeichenfolge zu lexen, wäre also:

lexStr :: String -> [String]
lexStr "" = []
lexStr s = 
    case lex s of
        [(tok,rest)] -> tok : lexStr rest
        []           -> error "Failed lex"

Um die Pedanten zu besänftigen, dieser Code ist in einer schrecklichen Form. Ein expliziter Aufruf von error anstatt einen vernünftigen Fehler zu melden, indem man Maybe in der Annahme, dass lex gibt nur 1 oder 0 Elemente zurück, usw. Der Code, der dies zuverlässig tut, ist etwa gleich lang, aber wesentlich abstrakter, so dass ich Ihre Anfängeraugen verschont habe.

3voto

OJ. Punkte 28189

Ich würde einen Blick auf Parsec und erstellen Sie eine einfache Grammatik zum Parsen Ihrer Zeichenketten.

0voto

Jakob Runge Punkte 2269

Wie wäre es, wenn man Worte benutzt). words :: String -> [String] und Wörter brauchen keine Leerzeichen

words "Hello World"
= words "Hello     World"
= ["Hello", "World"]

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X