Warum sind // und m // auch nicht genau?

8

Aus den folgenden Beispielen sehe ich, dass / / und m/ / nicht genau gleichbedeutend sind, im Gegensatz zu dem, was ich erwartet habe. Ich dachte, dass der einzige Grund, m/ / anstelle von / / zu verwenden, darin bestünde, dass verschiedene Begrenzer verwendet werden können (z. B. m{ } ). Warum sind sie anders und warum sollte ich einen gegen den anderen benutzen wollen?

Ich suche CSV-Dateien in einem Verzeichnis. Zuerst suchte ich nach Dateien, die in csv enden, also (der gesamte Code wird von der Perl 6 REPL angezeigt):

%Vor%

aber vor kurzem wurde eine Datei in Csv angezeigt. Also habe ich versucht, Groß- und Kleinschreibung insensitiv zu treffen:

%Vor%

Ich habe festgestellt, dass ich das beheben konnte, indem ich einen Block um den passenden Ausdruck legte:

%Vor%

Wenn ich jedoch einen Block um den ursprünglichen Ausdruck herum verwendet hätte, würde er nicht mit dem nackten / / übereinstimmen, aber mit m/ / :

%Vor%

Dann habe ich herausgefunden, dass es funktioniert, wenn ich das Adverb ohne Berücksichtigung der Groß- / Kleinschreibung in / / verwendet habe:

%Vor%

Wie auch immer, / / und m/ / verhalten sich eindeutig anders und mir ist noch nicht klar warum.

    
Christopher Bottoms 26.07.2017, 12:28
quelle

1 Antwort

9

Der Unterschied zwischen /.../ und m/.../

Von Regexes # Lexikalische Konventionen :

%Vor%

Mit anderen Worten, es sind /.../ und rx/.../ Synonyme, nicht /.../ und m/.../ :

  • /.../ und rx/.../ geben die angegebene Regex als Regex -Objekt zurück, ohne sie vorher mit irgendetwas zu vergleichen.
  • m/.../ stimmt sofort mit der angegebenen Regex mit der Zeichenfolge überein, die in der Variablen $_ (das so genannte "Thema") gespeichert ist, und gibt das Ergebnis als Match Objekt ein, oder als Nil , wenn keine Übereinstimmung gefunden wurde.

Demonstration:

%Vor%

Erklärungen & amp; Kommentare zu Ihrem Code

Regex-Modifikatoren anwenden

  

aber kürzlich erschien eine Datei mit der Endung Csv. Also habe ich versucht, Groß- und Kleinschreibung insensitiv zu treffen

%Vor%

Dieser Code entspricht sofort der Regex für das Thema $_ des aufrufenden Bereichs, der nicht initialisiert ist. Dies beinhaltet die Umwandlung in eine Zeichenfolge (die die Warnung Use of uninitialized value of type Any in string context verursacht) und gibt Nil zurück, da keine Übereinstimmung vorhanden ist. Also nennen Sie die Funktion im Wesentlichen als dir( test => Nil ) .

Damit es funktioniert, verwenden Sie rx oder wenden Sie das Adverb% :i in der Regex an:

%Vor% %Vor%

Blockiert als Smart-Matcher

  

Ich habe festgestellt, dass ich das beheben konnte, indem ich einen Block um den passenden Ausdruck legte:

%Vor%

Das funktioniert auch. Was hier passiert, ist:

  • { ... } erstellt einen Block, der ein einzelnes Argument akzeptiert (das als $_ im Block verfügbar ist).
  • Das m:i/ ... / innerhalb des Blocks stimmt mit $_ überein und gibt Match zurück.
  • Da m:i/.../ die letzte Anweisung im Block ist, wird ihr Match zum Rückgabewert des Blocks.
  • Das Adverb% test der Funktion dir akzeptiert jeden Smart-Matcher, der nicht nur Regex -Objekte, sondern auch Block -Objekte enthält (siehe Dokumentation für die Smart-Match-Operator ~~ ).

Verwenden Sie Regex als Bool

  

Wenn ich jedoch einen Block um den ursprünglichen Ausdruck herum verwendet hätte, würde er nicht mit dem bare // übereinstimmen, aber mit m / /:

%Vor%

Wenn ein Block als Smart-Matcher verwendet wird, wird er zuerst aufgerufen und dann wird sein Rückgabewert auf ein Bool gezwungen: True bedeutet, dass er übereinstimmt, und False bedeutet, dass dies nicht der Fall ist.

In diesem Fall gibt Ihr Block immer ein Objekt Regex zurück.

Wenn ein Regex-Objekt auf einen booleschen Wert angewendet wird, wird es sofort mit dem aktuellen $_ abgeglichen und gibt True zurück, wenn die reguläre Regex übereinstimmt, und "False, wenn nicht:

%Vor%

In Ihrem Code wird der Regex also wiederholt gegen $_ und nicht gegen die Dateinamen geprüft:

%Vor%

Filtern von Dateien nach ihrer Erweiterung

  

Ich suche CSV-Dateien in einem Verzeichnis. Zuerst suchte ich nach Dateien, die auf csv enden, also (der gesamte Code wurde von der Perl 6 REPL aus gesehen):

%Vor%

Hier finden Sie nicht nur Dateien mit der CSV-Erweiterung, sondern alle -Dateien, die in den drei Buchstaben cvs enden, einschließlich solcher wie foobarcsv oder foobar.xcsv .
Hier sind zwei bessere Möglichkeiten, um es zu schreiben, wenn Sie nur CSV-Dateien wollen:

%Vor% %Vor%

Oder die case-insensitive Version:

%Vor% %Vor%     
smls 26.07.2017, 15:27
quelle

Tags und Links