Thread Capturing und $1 (17 answers)
Opened by defun at 2008-07-25 02:38

defun
 2008-07-25 17:39
#112720 #112720
User since
2008-07-18
28 Artikel
BenutzerIn
[default_avatar]
moritz+2008-07-25 00:46:23--
Quote
NOTE: failed matches in Perl do not reset the match variables, which makes it easier to write
code that tests for a series of more specific cases and remembers the best match.

...
Capture-Variablen zu benutzen ohne vorher zu überprüfen ob die Regex überhaupt gemacht hat ist fast immer ein Fehler

Wahr. Aber wenn ich ein Pattern verwende, das einfach matchen MUSS, z.B. /(\t* *)/, dann sollte ich mir doch sicher sein können, oder? Aber weit gefehlt:

Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/usr/bin/perl

use strict;
use warnings;

my $text = '123';
pos $text = 3;
'f' =~ m/(.)/; # $1 befüllen
find() for 1 .. 2; # Mindestens zweimal, um den Fehler zu bekommen...

sub find
{
    $text =~ m/\G(.*)/gc;
    print $1, "\n";
}


Bei meiner Perl-Version verhält sich Perl beim ersten find() noch rational und setzt $1 auf einen leeren String, beim zweiten find() jedoch gibt es frustriert auf und lässt $1 auf 'f'. Das ist scheisse, wenn man einen Parser baut, der die \G-/gc-Methode verwendet, um einen Text Stück für Stück zu vernaschen, aber das Ende eines Strings (pos $string == length $string) nicht gesondert behandelt und einen "verbrauchten" String mehr als einmal antestet. Der Fehler entstand dann dadurch, dass ich $1 als Ergebniswert verwendet habe, obwohl es nicht den Match enthielt. Solange $1 undefiniert war, kam es zu keinem Fehler, aber sobald $1 irgendwo am Anfang des Programms gesetzt wurde, zerstörte der Wert in $1 die Logik des Programms. Eine üble Geschichte.

Richtig, ein Check auf den Rückgabewert des Regex hätte geholfen, aber wozu einen Rückgabewert testen, der per Definition wahr ist (wie ich dachte)? Wieder was gelernt...

View full thread Capturing und $1