R (Chandra) Chandrasekhar wrote:
Dear Folks,
This is a question about s///sg across lines from a file slurped in file
mode.
I am trying to change occurrences of & into &. As a minimal example,
I used the contrived file below where single- and multi-line records are
delimited by <...>. The only real-world text is a hyperlink from an
actual web site.
--------
<Pebbles & Pelicans>
<Hogsworthy Tales of a Late Summer Afternoon>
<Everything News
worthy & Printable>
# This is a comment and should be ignored
<Rough & Tumble>
<Pride & Prejudice>
<P&O Shipping Corporation>
<a
href=http://www.amazon.com/s?ie=UTF8&tag=mozilla-20&index=blended&link%5Fcode=qs&field-keywords=Programming%20Perl&sourceid=Mozilla-search>
<This record should not be
modified.>
<Nor this.>
<This is a very long line with many intervening & symbols This is a very
long line with many intervening & symbols This is a very long line with
many intervening & symbols This is a very long line with many
intervening & symbols This is a very long line with many intervening &
symbols This is a very long line with many intervening & symbols This is
a very long line with many intervening & symbols This is a very long
line with many intervening & symbols>
<sudo apt-get update && sudo apt-get upgrade>
--------
I tried this script on the above file:
--------
#!/usr/bin/perl
use warnings;
use diagnostics;
use strict;
my ($fh, $file, $data, $count, @record, $record);
my (@orig, $orig, @repl, $repl, $subs, @amper);
undef $/; # Slurp data in file mode
$file = shift;
open $fh, '<', $file or die "Cannot open $file: $!\n";
$data = <$fh>;
$count = 0;
while ($data =~ m|<\s*?(.*?)\s*?>|gis)
{
$count++;
print "$count: $1\n";
push @record, $1;
}
close $fh;
$count = 0;
foreach $record (@record)
{
$count++;
if (($record !~ m|&|s) && ($record =~ m|&|s))
{
push @orig, $record;
push @amper, $count;
$subs = ($record =~ s|&|&|gis); # Should be number of
substitutions
if ($subs == 0) {warn "$count: No replacement made.\n";}
else {print "$count: $subs replacement(s) made.\n";}
push @repl, $record;
}
}
foreach $orig (@orig)
{
$subs = 0;
$repl = shift @repl;
$count = shift @amper;
$subs = ($data =~ s|$orig|$repl|gs);
if ($subs == 0) {warn "$count: No replacement made.\n";} # Why?
else {print "$count: $subs replacement(s) made.\n";}
}
open $fh, '>', "$file.new" or die "Cannot open $file: $!\n";
print $fh $data;
close $fh;
--------
Why does the hyperlink string alone not get substituted at the end
although the replacement string has been correctly altered with five
substitutions?
Many thanks for your patience reading this long email.
Hello Chandra.
The line
$subs = ($data =~ s|$orig|$repl|gs);
is failing because the string in $orig contains regex metacharacters, in
particular the '?' signs.
$subs = ($data =~ s|\Q$orig|$repl|gs);
will escape all such metacharacters and you program should do what you
expect.
--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/