Was ist der Unterschied zwischen $ / und $ ¢ in Regex?


11

Wie der Titel schon sagt, was ist der Unterschied zwischen $/und ? Sie scheinen immer den gleichen Wert zu haben:

my $text = "Hello world";

$text ~~ /(\w+) { say $/.raku } (\w+)/;
$text ~~ /(\w+) { say $¢.raku } (\w+)/;

Beide führen zu Übereinstimmungsobjekten mit denselben Werten. Was ist die Logik bei der Verwendung übereinander?

Antworten:


11

Die Variable $/bezieht sich auf die letzte Übereinstimmung, während sich die Variable auf die letzte äußerste Übereinstimmung bezieht. In den meisten einfachen regulären Ausdrücken wie den oben genannten kann dies ein und dasselbe sein. Wie aus der Ausgabe der .rakuMethode hervorgeht, können MatchObjekte andere MatchObjekte enthalten (das erhalten Sie bei der Verwendung $<foo>oder $1für Captures).

Nehmen wir stattdessen an, wir hätten den folgenden regulären Ausdruck mit einer quantifizierten Erfassung

/ ab (cd { say $¢.from, " ", $¢.to } ) + /

Und lief es würde die folgende Ausgabe sehen, wenn wir mit "abcdcdcd" übereinstimmen:

0 2
0 4
0 6

Aber wenn wir verwenden , ändern zu $/, bekommen wir ein anderes Ergebnis:

2 2
4 4
6 6

(Der Grund dafür .toscheint zu sein, dass es - und .pos- erst am Ende des Erfassungsblocks aktualisiert wird.)

Mit anderen Worten, wird immer beziehen sich auf dem, was Ihr Endspiel Objekt (dh sein $final = $text ~~ $regex) , so dass Sie einen komplexen Erfassung Baum innerhalb der Regex genau durchqueren können , wie Sie nach der vollständigen Übereinstimmung So im obigen Beispiel beendet haben würden, könnten Sie einfach tun, $¢[0]um sich auf das erste Spiel, $¢[1]das zweite usw. zu beziehen .

In einem Regex-Codeblock $/wird auf die unmittelbarste Übereinstimmung verwiesen . Im obigen Fall ist dies die Übereinstimmung für das Innere der ( )und es werden weder die anderen Übereinstimmungen noch der ursprüngliche Beginn der Übereinstimmung bekannt: nur der Start für den ( )Block. Geben Sie also einen komplexeren regulären Ausdruck an:

/ a $<foo>=(b $<bar>=(c)+ )+ d /

Wir können jederzeit mit $ ¢ auf alle fooToken zugreifen, indem wir sagen $¢<foo>. Wir können die barZugriffstoken eines bestimmten foounter Verwendung $¢<foo>[0]<bar>. Wenn wir einen Codeblock in foodie Erfassung einfügen , kann er barmit $<bar>oder auf Token zugreifen $/<bar>, aber nicht auf andere foos.


1
Oh! Ich interpretierte das Dokument "Der Hauptunterschied zwischen $/und ist Umfang: Letzteres hat nur einen Wert innerhalb des regulären Ausdrucks" als bloße Spur, so wie es Cursorist. Als ich Ihre Antwort las, dachte ich, wäre das, was $*TOPich in der A möglichen Verbesserung geschaffen habe? Abschnitt meiner Antwort auf die SO "Warum / wie wird eine zusätzliche Variable benötigt, um wiederholte willkürliche Zeichen mit Erfassungsgruppen abzugleichen?". Aber meine Versuche zu ersetzen $*TOPmit fehlgeschlagen. Verstehst du meinen Punkt in dieser Antwort? Schaffst du es zum Laufen?
Raiph

Raiph: Also in Grammatiken, wird für jedes Token erneuert, also müsste man $*TOP := $¢im TOPToken sagen, aber das macht die Notwendigkeit für das $*TOPvar natürlich nicht überflüssig . Ich bin damit einverstanden, dass es fantastisch wäre, sich auf Spiele auf höchstem Niveau beziehen zu können. Das Problem ist letztendlich immer noch das, das Sie identifizieren: Wenn die Position / der Hash mit dem Beitrag zum Übereinstimmungsobjekt übereinstimmt. Bei Verwendung von - was pro Token ist - werden die Ergebnisse per Definition veröffentlicht, sobald der umschließende { }Block angetroffen wird.
user0721090601

Was mich interessiert ist, dass ich es bei der Entwicklung Binexnicht als rechnerisch schlechter empfunden habe, Spielergebnisse sofort zu veröffentlichen, wenn ich auf sie stoße. Am Ende des Tages pushen / knallen Sie entweder in eine zwischengespeicherte Liste / einen zwischengespeicherten Hash oder Sie pushen / knallen in die Liste / den Hash des Spiels. Es kann jedoch eine Art interne Beschleunigung geben, von der ich nicht weiß, dass sie für LTM verwendet wird, was wahrscheinlich der Kern davon ist (das { }beendet ein Token für die Zwecke von LTM und wird daher eher ausgeführt / getestet als der Rest des Tokens in einer |Gruppierung)
user0721090601

Ähhh. Ich war zu dem Schluss gekommen, dass es dynamisch war, und war überrascht, als es nicht funktionierte. Aber der Penny ist jetzt gefallen, dass es lexikalisch ist, wie ich hätte erraten können, wenn Sie das Wort "äußerste" verwendet haben, und wie Sie erklären, zu Beginn jeder Regel festgelegt ist.
Raiph

Daher wird zu Beginn einer Regel ein neues Übereinstimmungsobjekt erstellt, das die Cursorposition der übereinstimmenden Engine innerhalb der ursprünglichen Eingabezeichenfolge aufzeichnet, ansonsten aber leer ist. (Richtig?) Dann und $/sind an dasselbe Objekt gebunden, nämlich an dieses neue Übereinstimmungsobjekt, das aufzeichnet, was mit dieser Regel übereinstimmt, und im Verlauf erfasst. Wenn der Abgleich fortschreitet, bleibt er an dieses gesamte Übereinstimmungsobjekt gebunden, während er $/jedes Mal neu erstellt wird, wenn ein neues Übereinstimmungsobjekt erstellt wird, sodass er, wie Sie sagen, immer dem neuesten Übereinstimmungsobjekt entspricht. Recht?
Raiph
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.