2015-06-05 19 views
5

Ich benutze Regex in Perl. Eines der Dinge, die ich kenne:Was bedeutet s/ G/0/g?

my $n = " 49 here"; 
$n =~ s/\G /0/g; 
print $n; 

Das gibt:

00049 here 

Ich kenne den s Modifikator (einzeilig). Ich verstehe auch den Modifikator g (global, der die letzte Spielposition verfolgt). Ich weiß, dass die Regex etwas durch Nullen ersetzt, aber ich verstehe nicht, was die \G UND die folgenden Leerzeichen tun (ohne das folgende Leerzeichen \G das Ergebnis ist: 0 49 here).

+0

'\ G' heißt das G-Anker-Konstrukt. Es bedeutet, dass es übereinstimmen muss, wo das letzte erfolgreiche Spiel endete. – sln

+2

"Ich kenne den' s' Modifikator (einzeilig). " Ich denke, Sie verwechseln das mit dem Substitutionsoperator. 's' Modifikator:'/foo/s' Substitutionsoperator: 's/foo/bar /' – ThisSuitIsBlackNot

+0

Ja in der Tat, danke fürs Aufräumen! – Agnaroc

Antwort

4

\G die G-Anchor Konstrukt genannt wird. Es bedeutet, dass es übereinstimmen muss, wo das letzte erfolgreiche Spiel endete. Bevor ein Regex startet, ist \G (wirklich eine Flagge) true, so wird es als wahr beginnen, dann nach einem Leerzeichen suchen, es finden, immer noch wahr, findet das nächste, etc .. Wenn es kein Leerzeichen findet, \G Flag wird falsch und bleibt (in diesem Fall).

Ohne es sucht es irgendwo im String statt nur am Anfang.

$ perl -E'my $n = " 49 here"; $n =~ s/\G /0/g; say $n' 
00049 here 

$ perl -E'my $n = " 49 here"; $n =~ s/ /0/g; say $n' 
000490here 

/\G/g wird Übereinstimmen (nichts) nur 1-mal am Anfang der Zeichenfolge nur, weil Perl nicht zurückkehren wird genau das gleiche Spiel (definiert als die gleiche Ausgangsposition und gleiche Länge) zweimal. Deshalb ist es ein 0 dort hinzufügt und stoppt in dem folgenden:

In Perl, die Position, an der das letzte Spiel beendet ist mit der Variablen zugeordnet ist abgestimmt (nicht der Betreiber). Es kann mit der Funktion pos beobachtet und geändert werden. \G Flag bleibt mit der Variablen, nicht die Regex. Da es mit der Variablen verknüpft ist, die in einer nachfolgenden Anwendung einer anderen Regex zugeordnet wird, beginnt \G mit dem letzten verbleibenden Spiel.

$ perl -E'my $n = "abcdefabc"; $n =~ /def/g; $n =~ s/\Gabc/ABC/; say $n' 
abcdefABC 
+2

Ich glaube nicht, dass es hier missbraucht wird - die Intention scheint zu sein, eine durch Leerzeichen gefüllte Zahl am Anfang der Zeile in eine Null-aufgefüllte Zahl zu konvertieren, so dass die Übereinstimmung nach dem String-Initial-Leerzeichen nicht beabsichtigt ist. – psmears

+0

Ah, ich sehe Sie die Antwort aktualisiert, als ich meinen Kommentar schrieb :) – psmears

+0

@psmears - Sicher könnte das die Absicht sein, aber wer weiß. Ich weiß, 20 andere sollten es in Perl machen. – sln

2

In Perl bestätigt \G die Position am Ende der vorherigen Übereinstimmung oder den Anfang der Zeichenfolge für die erste Übereinstimmung.

Deshalb werden Leerzeichen am Anfang und alle folgenden Leerzeichen danach durch 0 ersetzt, aber Leerzeichen nach 49 unverändert.

RegEx Demo (Verwendet PCRE statt Perl, aber \G bedeutet dasselbe in diesem Motor)

+0

Ich verstehe, aber warum tut das: $ n = ~ s/\ G/0/g; Gibt dies als Ausgabe: 0 49 hier Während dieser: $ n = ~ s/\ G/0/g; gibt dies als Ausgabe: 00049 hier Beachten Sie, dass ich Perl hier verwende (beachten Sie die Leerzeichen im ersten Code) Ich sah Ihre Regex-Demo, aber das erklärt immer noch nicht, warum die Leerzeichen benötigt werden :( – Agnaroc

+0

First 's 'ist für ** Ersatz ** -Befehl und' \ G 'ist Muster mit' 0' als Ersatz. 'g' ist für global. – anubhava

+0

Aber was bedeutet das Leerzeichen? – Agnaroc