I recently decided to transform all figures (made with the language "pic", part of
groff) in my course files from inches to mm. Roughly, this means multiplying
numbers by 25.4, but life is more complicated: some numbers are Boolean, others
are just quantities or proportions. It is necessary to scan the context carefully.
This is a typical job for perl, and I like writing such one-time scripts. Just
before I made the program run over several hundreds of files, a last check showed
that occasional numbers had escaped rescaling. The exception pattern was so
obvious that I immediately found the piece of code that should have fetched them.
However, I couldn't make it work.
To find the real problem, I selected the relevant fragment of the program and
simplified it as much as possible while still producing the "error":
my @attempts = ( "a c,d", "a b,d", "x c,d", "a b x c,d" );
ATTEMPT: foreach ( @attempts ) {
MATCH: while ( m/\G([ax] +)([bc][a-z +]*),[a-z]+/gc ) {
my $patstart = $1;
my $before_comma = $2;
if ( $before_comma =~ m/^b/ ) {
print "reject $_ at '$patstart'\n";
next MATCH;
}
print "accept $_ at '$patstart'\n";
next ATTEMPT;
}
print "rejected $_ at all positions\n"
}
Roughly speaking, I have to inspect a string on a certain pattern to start at
(here I took "a" and "x"), then look for a few consecutive parts. One part has to
be inspected more closely in turn (here, a simple test on the first character
which may not be 'b'). If that works fine, the real activity can be performed
(here: merely printing a message), otherwise, the matching must go on.
I use four "attempt" strings. Here is the output:
accept a c,d at 'a '
reject a b,d at 'a '
rejected a b,d at all positions
accept x c,d at 'x '
reject a b x c,d at 'a '
rejected a b x c,d at all positions
The last one is the error: it should be accepted at 'x'. It seems as if m//g
refuses to match in an area where it has been matching before. In desperation, I
even tried all on/off combinations of a modifier 'c' and '\G'; it makes no difference.
What's wrong with this m//g? It works fine in very similar situations.
Actually, I found a different approach that works fine (by using a list of pattern
starts), but I am too stubborn to leave an error without understanding it.
--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/