Re: Character class in an array
by dws (Chancellor) on Sep 17, 2002 at 17:21 UTC
|
This works well, except that it also accepts space(' ') as a valid character.
This is because of array interpolation, which uses the contents of $" to separate array elements when joining them together. You can use this to your advantage by doing something like
@a = ( 'a', 'x', 'z' ); # simplified array
while(<>)
{
local $" = "";
print if(/^[@a]{3}$/);
}
Note that this re-localizes $" within a loop, which isn't the most effecient approach, but then again you might not notice the performance difference without a microsocope.
| [reply] [d/l] [select] |
Re: Character class in an array
by Nemp (Pilgrim) on Sep 17, 2002 at 17:18 UTC
|
Hi,
If I understand your problem correctly it is being caused by the default list seperator $" which is set to a space as default. This is used to seperate array values interpolated into a string hence your regex is also allowing spaces in the character class, which I believe is becoming [a x z] in your example above.
I tried code similar to yours with the following line added before the interpolation and it worked fine for me.
$" = '';
HTH, Neil
Note: all opinion in this post is from a newbie, "wow I think I understood something!" point of view :) | [reply] [d/l] [select] |
Re: Character class in an array
by RMGir (Prior) on Sep 17, 2002 at 17:37 UTC
|
Others have explained that $" is the source of your problem.
However, there are other problems with what you're doing.
You're repeating that interpolation on every trip through the loop, when you could be using qr// to compile your regex once and then forget about it.
Here are some comparisons of a few of the other solutions mentioned in this thread, along with one where the regex is pre-built with qr//. These results are with 5.6.1 on cygwin; YMMV.
$ perl testLocal.pl
Benchmark: running localWhile, localWhileQR, whileLocal, each for at l
+east 3 CPU seconds...
localWhile: 4 wallclock secs ( 3.02 usr + 0.00 sys = 0.02 CPU) @ 28
+894.20/s (n=87116)
localWhileQR: 4 wallclock secs ( 3.17 usr + 0.01 sys = 3.18 CPU) @
+45765.70/s (n=145718)
whileLocal: 4 wallclock secs ( 3.09 usr + 0.00 sys = 3.09 CPU) @ 20
+884.62/s (n=64617)
Rate whileLocal localWhile localWhileQR
whileLocal 20885/s -- -28% -54%
localWhile 28894/s 38% -- -37%
localWhileQR 45766/s 119% 58% --
The benchmark code is here:
--
Mike | [reply] [d/l] [select] |
|
| [reply] [d/l] |
|
| [reply] |
|
|
| [reply] |
|
|
Re: Character class in an array
by fglock (Vicar) on Sep 17, 2002 at 17:13 UTC
|
you are getting [a x z] instead of
[axz] when you say [@a]
Are you sure your join used an
empty string? That is, '' instead of
' '
Try:
$tmp = join('',@a);
print if /^[$tmp]{3}$/;
| [reply] [d/l] [select] |
Re: Character class in an array
by japhy (Canon) on Sep 17, 2002 at 17:32 UTC
|
You can localize $" to the empty string, or just use a scalar instead:
my @a = qw( a x z );
{
local $" = "";
while (<>) {
print if /^[@a]{3}$/; # /o might be good, too
}
}
or
my @a = qw( a x z );
my $re = join '', @a;
while (<>) {
print if /^$re$/; # again, /o might help
}
_____________________________________________________
Jeff[japhy]Pinyan:
Perl,
regex,
and perl
hacker, who'd like a job (NYC-area)
s++=END;++y(;-P)}y js++=;shajsj<++y(p-q)}?print:??; | [reply] [d/l] [select] |
Re: Character class in an array
by zigdon (Deacon) on Sep 17, 2002 at 17:16 UTC
|
When I tried to use this code with the join('', @a) everything worked ok?
I think that what's happening here is that @a is getting interpolated as if in a double quoted string - with $" as as the seperator, which is space by default. The fact that it works with the join seems to agree with this theory.
-- Dan | [reply] [d/l] [select] |
Re: Character class in an array
by BrowserUk (Patriarch) on Sep 17, 2002 at 17:20 UTC
|
Update: nemp's post above this got it first and got it right.
It should be $" not $, Below corrected.
@a = ( 'a', 'x', 'z' ); # simplified array
{ # restrict scope of changes to $,
local $"=''; # change from default space to null string
while(<>)
{
print if(/^[@a]{3}$/);
}
}
Cor! Like yer ring! ... HALO dammit! ... 'Ave it yer way! Hal-lo, Mister la-de-da. ... Like yer ring! | [reply] [d/l] |
Re: Character class in an array
by Aristotle (Chancellor) on Sep 17, 2002 at 21:23 UTC
|
Another option over using $" is to inline the join in your regex.
my @a = ( 'a', 'x', 'z' );
my $match = qr/^[@{[ join '', @a ]}]{3}$/;
while(<>)
{
print if /$match/;
}
You can embed Perl inside any literal strings in this fashion.
Makeshifts last the longest. | [reply] [d/l] |