Schrift
[thread]8732[/thread]

join (//, @buffer): join mit // hängt von Matching ab (Seite 2)



<< |< 1 2 >| >> 17 Einträge, 2 Seiten
sid burn
 2007-02-08 17:10
#74108 #74108
User since
2006-03-29
1520 Artikel
BenutzerIn

user image
Code: (dl )
1
2
3
4
5
my $dummy = "Y";
my @buffer = qw(a b c d);

$dummy =~ /Y/i;
print join(//,@buffer),"\n";


Du lässt $dummy gegen Y matchen. $dummy matcht also erfolgreich. // ist also jetzt auf die Regex /Y/i gesetzt.

Dein join ausgeschrieben bedeutet folgendes:

Code: (dl )
join( $_ =~ m/Y/i, @buffer)


$_ ist bei dir nicht gesetzt. Es matcht also nie. Der Rückgabewert des Matches ist undef. Dieses undef wird nun benutzt als Kleber um die Werte zusammen zu fügen.

Hättest du z.B. vorher $_ auf 'Y' gesetzt, dann würde es matchen und der Rückgabewert ist wahr (1). Dieser Wert wird dann als Kleber benutzt.




Code: (dl )
1
2
3
4
5
my $dummy = "Y";
my @buffer = qw(a b c d);

$dummy =~ /N/i;
print join(//,@buffer),"\n";


Naja hier das gleiche in Grün.
Allerdiengs matcht jetzt $dummy nicht auf =~ /N/i;
Das hat zur Folge das // eine Leere Regex bleibt.

Dein join ausgeschrieben bedeutet wieder folgendes:
Code: (dl )
join( $_ =~ //, @buffer)


Da du noch keine gematchte Regex hast, hast du hier eine Leere Regex drin stehen. Eine Leere Regex matcht ebenfalls auf einen Leeren String. $_ ist ja noch Leer bei dir.

Die Regex ist also wahr und gibt 1 als Wert zurück. Dieses wird nun wiederrum als Kleber benutzt.



War doch einfach.
Nicht mehr aktiv. Bei Kontakt: ICQ: 404181669 E-Mail: perl@david-raab.de
sid burn
 2007-02-08 17:21
#74109 #74109
User since
2006-03-29
1520 Artikel
BenutzerIn

user image
[quote=betterworld,08.Feb..2007, 16:05][quote=pq,08.02.2007, 09:41]perlre, "Repeated patterns matching zero-length substring"
aber verstehen muss man das nicht =)[/quote]
Dies hingegen bezieht sich nicht auf leere Patterns, sondern auf Patterns, die auf leere Strings matchen.[/quote]
Nicht ganz.
Es bezieht sich auf matches die kein Text Konsumieren. Kein text wird auch durch (?= ) erreicht. Zero-Width sind alle Sachen wie Lookahead, Lookbehind etc.

Als Beidpiel wurde ja
Code: (dl )
"foo" =~ m/(o?)*/;

genannt. Dies würde eine unendliche Schleife sein.

Den die Regex Engine fängt an das "f" mit dem "o" zu Vergleichen. Das matcht nicht. Aber da ja hinter dem o ein Fragezeichen ist bedeutet es, der matcht ist auch erflogreich wenn kein o vorkommt.

Die Regex Engine steht also immer noch beim "f" und springt kein Zeichen weiter. Naja und durch das * wird jetzt der Ausdruck o? wieder auf das f angewendet.

Naja eine endlosschleife halt. Problem ist halt das kein text Konsumiert wird, also die Regex Engine nie ein Zeichen weiter Springt. Gleiche Problematik könnte man auch mit den gesagt Lookaheads zusammen bauen.


EDIT:
Achso, das mit dem Zero-length bedeutet nur das Perl solche infinity Loops automatisch erkennt. Und anstatt ständig und endlich oft immer wieder gegen das "f" zu matchen, springt die Regex Engine bei Perl halt automatisch ein Zeichen weiter. Somit werden diese Loops halt vermieden.\n\n

<!--EDIT|sid burn|1170948733-->
Nicht mehr aktiv. Bei Kontakt: ICQ: 404181669 E-Mail: perl@david-raab.de
Dubu
 2007-02-08 21:10
#74110 #74110
User since
2003-08-04
2145 Artikel
ModeratorIn + EditorIn

user image
[quote=betterworld,08.02.2007, 16:01][quote=Dubu,07.02.2007, 18:14]Und der Rückgabewert des Pattern-Matches ist die Anzahl der Treffer...[/quote]
Nee, es ist nur 1 oder "", je nach dem, ob das Pattern matcht oder nicht.  Und "1" und "" sind auch gerade die Strings, die offenbar zum joinen benutzt wurden.[/quote]
Ah, ja, natürlich.

Deshalb muss man ja auch extra diese Konstruktion mit dem leeren Array benutzen, wenn man nur die Anzahl der Treffer haben will:
Code: (dl )
$num = () = $str =~ /pattern/g;
Dubu
 2007-02-08 21:12
#74111 #74111
User since
2003-08-04
2145 Artikel
ModeratorIn + EditorIn

user image
[quote=betterworld,08.02.2007, 16:05]In perlop steht die Sache mit dem leeren Pattern auch beschrieben:
Quote
              If the PATTERN evaluates to the empty string, the last success-
              fully matched regular expression is used instead. In this case,
              only the "g" and "c" flags on the empty pattern is honoured -
              the other flags are taken from the original pattern. If no
              match has previously succeeded, this will (silently) act
              instead as a genuine empty pattern (which will always match).
[/quote]
Ah, danke für die Aufklärung!
Das erklärt, warum gerade dann eine "1" zurück geliefert wird, wenn der Match nicht klappt.
sid burn
 2007-02-09 00:46
#74112 #74112
User since
2006-03-29
1520 Artikel
BenutzerIn

user image
[quote=Dubu,08.Feb..2007, 20:12][quote=betterworld,08.02.2007, 16:05]In perlop steht die Sache mit dem leeren Pattern auch beschrieben:
Quote
If the PATTERN evaluates to the empty string, the last success-
fully matched regular expression is used instead. In this case,
only the "g" and "c" flags on the empty pattern is honoured -
the other flags are taken from the original pattern. If no
match has previously succeeded, this will (silently) act
instead as a genuine empty pattern (which will always match).
[/quote]
Ah, danke für die Aufklärung!
Das erklärt, warum gerade dann eine "1" zurück geliefert wird, wenn der Match nicht klappt.[/quote]
Es wird nirgendswo eine 1 zurück geliefert, wenn der match nicht klappt.
Nicht mehr aktiv. Bei Kontakt: ICQ: 404181669 E-Mail: perl@david-raab.de
Dubu
 2007-02-09 00:54
#74113 #74113
User since
2003-08-04
2145 Artikel
ModeratorIn + EditorIn

user image
[quote=sid burn,08.02.2007, 23:46]Es wird nirgendswo eine 1 zurück geliefert, wenn der match nicht klappt.[/quote]
Sorry, vielleicht habe ich mich unklar ausgedrückt: Es wird eine 1 zurück geliefert, da der vorige Match nicht klappt.
Siehe das Problem aus dem ersten Beitrag:
Code: (dl )
1
2
3
4
5
my $dummy = "Y";
my @buffer = qw(a b c d);

$dummy =~ /N/i;
print join(//,@buffer),"\n";

Das ergibt a1b1c1d.
Das meinte ich. Da der Match mit /N/ nicht gepasst hat, liefert das // später im skalaren Kontext immer eine 1.
sid burn
 2007-02-09 01:35
#74114 #74114
User since
2006-03-29
1520 Artikel
BenutzerIn

user image
[quote=Dubu,08.Feb..2007, 23:54][quote=sid burn,08.02.2007, 23:46]Es wird nirgendswo eine 1 zurück geliefert, wenn der match nicht klappt.[/quote]
Sorry, vielleicht habe ich mich unklar ausgedrückt: Es wird eine 1 zurück geliefert, da der vorige Match nicht klappt.
Siehe das Problem aus dem ersten Beitrag:
Code: (dl )
1
2
3
4
5
my $dummy = "Y";
my @buffer = qw(a b c d);

$dummy =~ /N/i;
print join(//,@buffer),"\n";

Das ergibt a1b1c1d.
Das meinte ich. Da der Match mit /N/ nicht gepasst hat, liefert das // später im skalaren Kontext immer eine 1.[/quote]
Nein,
der vorherige Match hat nicht geklappt. Daher hat // keine weitere bedeutung. Nur wenn der vorherige Matcht geklappt hätte würde // auf den letzten Match gesetzt werden.

Da bisher noch kein Match geklappt hat entspricht // halt einer Leeren Regex.

Und wenn man keine Variable angibt dann wird automatisch auf $_ gematcht.

Das hat zur folge das ein Leerer Match immer wahr wird. Und dies hat den Rückgabewert 1.


Das // hat nichts direkt mit dem vorherigen Match zu tun, und dass er nicht gematcht hat. Würdest du den vorherige Match raus löschen würde immer noch das gleiche heraus kommen.

$dummy =~ /N/i;

hat keinen Einfluss auf das Ergebnis, da es eben nicht matcht, und somit // nicht verändert. Es kommt das gleiche Ergebniss raus, auch wenn du den ganzen Match weg lässt.

Code: (dl )
1
2
3
my $dummy = "Y";
my @buffer = qw(a b c d);
print join(//,@buffer),"\n";


Hierbei kommt wie gesagt immer noch "a1b1c1d" heraus.\n\n

<!--EDIT|sid burn|1170978477-->
Nicht mehr aktiv. Bei Kontakt: ICQ: 404181669 E-Mail: perl@david-raab.de
<< |< 1 2 >| >> 17 Einträge, 2 Seiten



View all threads created 2007-02-07 10:35.