Rebol2 hat eine / ANY-Verfeinerung in der FIND-Funktion, die Platzhaltersuchen durchführen kann:
%Vor%Ich benutze dies ausgiebig in engen Schleifen, die gut funktionieren müssen. Aber die Verfeinerung wurde in Rebol3 entfernt.
Was ist der effizienteste Weg, dies in Rebol3 zu tun? (Ich vermute eine parse
Lösung irgendeiner Art.)
Ich habe Ihre Frage nach "Klarheit" bearbeitet und sie so geändert, dass sie "entfernt" wurde. Das klang nach einer bewussten Entscheidung. Es stellt sich jedoch heraus, dass es möglicherweise nicht implementiert wurde.
ABER wenn jemand mich fragt, ich denke nicht, dass es in der Box sein sollte ... und nicht nur, weil es eine lausige Verwendung des Wortes "ALL" ist. Hier ist warum:
Sie suchen nach Mustern in Zeichenketten ... wenn Sie also gezwungen sind, eine Zeichenkette zu verwenden, um dieses Muster zu spezifizieren, bekommen Sie "Meta" -Probleme. Nehmen wir an, ich möchte das Wort *Rebol*
oder ?Red?
extrahieren, jetzt muss es entkommen und die Dinge werden wieder hässlich. Zurück zu RegEx. : - /
Also, was Sie vielleicht wollen wollen, ist kein STRING! Muster wie s?r
, aber ein BLOCK! Muster wie ["s" ? "r"]
. Dies würde Konstrukte wie ["?" ? "?"]
oder [{?} ? {?}]
zulassen. Das ist besser, als den String-Hacker, den jede andere Sprache verwendet, erneut zu verwenden.
Und das ist, was PARSE tut, wenn auch auf eine etwas weniger deklarative Art und Weise. Es verwendet auch Wörter anstelle von Symbolen, wie Rebol es gerne tut. [{?} skip {?}]
ist eine Übereinstimmungsregel, in der skip
eine Anweisung ist, die die Analyseposition nach jedem einzelnen Element der Parse-Reihe zwischen den Fragezeichen verschiebt. Es könnte dies auch tun, wenn es einen Block als Eingabe analysiert und [{?} 12-Dec-2012 {?}]
entspricht.
Ich weiß nicht genau, was das Verhalten von / ALL mit etwas wie "ab ?? c de ? * f" wäre oder wäre, wenn es eine alternative Musterlogik vorsieht oder was. Ich nehme an, die Rebol2-Implementierung ist kurz? Wahrscheinlich stimmt es nur mit einem Muster überein.
Um eine Grundlinie zu setzen, hier ist eine möglicherweise lahme PARSE Lösung für die s?r
Absicht:
Wenn Sie möchten, dass es s*r
ist, würden Sie skip "r" return pos
in to "r" return pos
ändern.
Bei einer Effizienznotiz erwähne ich, dass in der Tat Zeichen schneller mit Zeichen verglichen werden als Strings. So machen to #"s"
und #"r" to end
beim Parsen von Strings im Allgemeinen einen messbaren Unterschied in der Geschwindigkeit. Darüber hinaus bin ich mir sicher, dass andere es besser können.
Die Regel ist sicherlich länger als "s?r"
. Aber es ist nicht das lang, wenn Kommentare herausgenommen werden:
(Hinweis: Es gibt Pos: wie geschrieben. Ist ein USE in PARSE implementiert oder geplant?)
Es ist eine schöne Sache, dass es in allen Entscheidungsmomenten Hakenpunkte bietet und ohne die austretenden Defekte eine naive String-Lösung hat. (Ich bin versucht, meine übliche "Bad LEGO Alligator vs Gute LEGO Alligator " Rede.)
Aber wenn Sie nicht direkt in PARSE programmieren wollen, dann scheint die wirkliche Antwort eine Art zu sein "Glob Expression" -PARSE-Compiler. Es könnte die beste Interpretation von glob sein, die Rebol hätte, weil du eine einmalige Sache machen könntest:
%Vor%Oder, wenn Sie das Match oft machen, cachen Sie den kompilierten Ausdruck. Stellen wir uns auch vor, unsere Blockform verwendet Wörter für die Alphabetisierung:
%Vor% Es könnte interessant sein, einen solchen Compiler auch für regex zu sehen. Diese akzeptieren möglicherweise nicht nur String-Eingaben, sondern blockieren auch Eingaben, so dass sowohl "s.r"
als auch ["s" . "r"]
legal sind ... und wenn Sie das Block-Formular verwenden, müssen Sie nicht flüchten und ["." . "."]
schreiben, um mit% übereinzustimmen. co_de%
Ziemlich interessante Dinge wären möglich. Gegeben in RegEx:
%Vor%Rebol könnte modifiziert werden, um entweder die Zeichenfolgenform oder das Kompilieren in eine PARSE-Regel mit einer Form wie folgt zu übernehmen:
%Vor%Dann bekommst du eine Dialektvariante, die nicht zu entkommen ist. Entwerfen und Schreiben solcher Compiler ist eine Übung für den Leser. : -)
Ich habe das in zwei Funktionen aufgeteilt: eine, die eine Regel erstellt, die dem angegebenen Suchwert entspricht, und die andere, um die Suche durchzuführen. Wenn Sie die beiden trennen, können Sie denselben generierten Syntaxblock wiederverwenden, in dem ein Suchwert über mehrere Iterationen hinweg angewendet wird:
%Vor%Wenn Sie die Funktion aufteilen, erhalten Sie auch eine Basis, um die zwei unterschiedlichen Probleme zu optimieren: den Anfang finden und den Wert abgleichen.
Ich ging mit PARSE, obwohl *?
scheinbar einfache Regeln sind, es gibt nichts, das so ausdrucksstark und schnell ist wie PARSE, um eine solche Suche effektiv zu implementieren.
Es könnte nach @HostileFork noch so sein, einen Dialekt anstelle von Strings mit Platzhaltern zu betrachten - in der Tat bis zu dem Punkt, an dem Regex durch einen Compile-to-Parse-Dialekt ersetzt wird, aber vielleicht den Rahmen der Frage übersteigt.
>