How to make this nested loop a continuation in perl?
Here is my code:
#!perl -w
use strict;
my %hash = (
1 => "a",
2 => "b",
);
foreach my $num ( keys %hash ) {
while (<DATA>) {
s/$num/$hash{$num}/g;
print;
}
}
__DATA__
121212
11111
222
I intend to replace all numbers with the corresponding values existing in the hash. But he deduces:
a2a2a2
aaaaa
222
Hit any key to close this window...
Why does the foreach loop run only once? Who can explain this to me? And how do I change the code? I want it to output:
ababab
aaaaa
bbb
Thanks in advance.
The reason the loop foreachonly appears once is because you are reading from <DATA>one line at a time. The second time you loop the outer loop, there is no more data to read from the data in your inner loop. Instead, why don't you read everything <DATA>in the list first:
@mylist = <DATA>
And then iterate over this list in your inner loop.
, , , .
, script, @Benj answer , , , , keys perl perl.
, , . script . , .
#!perl -w
use strict;
my %hash = qw(1 a 11 zz 2 b);
my $pat = join '|',
map qr/\Q$_\E/,
sort { length $b <=> length $a }
keys %hash
;
while (<DATA>) {
s/($pat)/$hash{$1}/g;
print;
}
__DATA__
121212
11111
222
:
ababab zzzza bbb
- , , DATA eof foreach. , .
, / 1, , tr///.
use strict;
use warnings;
while (<DATA>) {
tr/12/ab/;
print;
}
__DATA__
121212
11111
222
. , tr/// , .
, Sinan, / 1. , 1 11, ? , , :
my %hash = qw(1 a 2 b);
while (<DATA>) {
s|(.)| $hash{$1} // $1 |ge;
print;
}
regex /e, RHS . //. , , , , , .
if (defined $hash{$1}) {
$hash{$1};
} else {
$1;
}
defined $hash{$1} ? $hash{$1} : $1
, (.), .
- foreach while,
#!perl -w
use strict;
my %hash = (
1 => "a",
2 => "b",
);
while (<DATA>) {
foreach my $num ( keys %hash ) {
s/$num/$hash{$num}/g;
}
print;
}
__DATA__
121212
11111
222
As others pointed out, the problem with the source program was the read position of the file descriptor DATA. The function is rewindusually used to reset the position of the file descriptor at the beginning so that it can be read again, but in the specific case DATAit does not work properly due to the fact that the descriptor is really just a built-in file descriptor in the file itself .pl. However, you can save the position with tell, and then reset back for each iteration with seek:
#!perl -w
use strict;
use Fcntl qw( SEEK_SET );
my %hash = (
1 => "a",
2 => "b",
);
my $pos = tell DATA;
foreach my $num ( keys %hash ) {
seek DATA, $pos, SEEK_SET;
while (<DATA>) {
s/$num/$hash{$num}/g;
print;
}
}
__DATA__
121212
11111
222
Gives output:
a2a2a2
aaaaa
222
1b1b1b
11111
bbb