Home > Archive > PERL Beginners > January 2008 > list or hash of replacement regex
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
list or hash of replacement regex
|
|
| Bingfeng Zhao 2008-01-22, 4:07 am |
| Hi list,
I'm in trouble and hope who can work me out.
I want to so some replacements, so I want to keep all replacement
policies in a hash so that I can use them in a foreach loop, such as:
my %policies = (
"abc" => "def",
"jfk\s+" => "jfk ",
"(\d+)uu" => "uu\1"
#... many policies here
);
foreach (<DATA> )
{
s/$_/$policies{$_}/g for keys %policies;
print;
}
But perl complains, so I update it as:
my %policies = (
qr/abc/ => "def",
qr/jfk\s+/ => "jfk ",
qr/\d+uu/ => "uu\1"
);
foreach (<DATA> )
{
s/$_/$policies{$_}/g for keys %policies;
print;
}
The result is wrong, since I got \1 instead of matched part. I update it
again as:
my %policies = (
qr/abc/ => qr/def/,
qr/jfk\s+/ => qr/jfk /,
qr/\d+uu/ => qr/uu\1/
);
foreach (<DATA> )
{
s/$_/$policies{$_}/g for keys %policies;
print;
}
Perl complains again that \1 is not refer to anything. So I try to put
the whole s/// into a list:
my $policies = (
s/abc/def/g,
s/jfk\s+/jfk /g,
s/\d+uu/uu\1/g
);
foreach (<DATA> )
{
$_ =~ $_ for $policies;
print;
}
It generates more errors. So my question, how can I save my replacement
policies in perl data structure so that I can use it just as single one?
Best regards,
Bingfeng
| |
| Jeff Pang 2008-01-22, 4:07 am |
|
-----Original Message-----
>From: "Zhao, Bingfeng" <Bingfeng.Zhao@ca.com>
>Sent: Jan 22, 2008 4:53 PM
>To: beginners@perl.org
>Subject: list or hash of replacement regex
>
>But perl complains, so I update it as:
>my %policies = (
> qr/abc/ => "def",
> qr/jfk\s+/ => "jfk ",
> qr/\d+uu/ => "uu\1"
> );
For a first look, you may reversed the hash's keys and values.
Constructing it as below is better.
%policies = (
'def' => qr/abc/,
'jfk' => qr/jfk\s+/,
....);
Regards,
Jeff Pang
| |
| John W. Krahn 2008-01-22, 8:09 am |
| Zhao, Bingfeng wrote:
> Hi list,
Hello,
> I'm in trouble and hope who can work me out.
> I want to so some replacements, so I want to keep all replacement
> policies in a hash so that I can use them in a foreach loop, such as:
>
> my %policies = (
> "abc" => "def",
> "jfk\s+" => "jfk ",
> "(\d+)uu" => "uu\1"
You are using double quoted strings so the backslashes will be
interpolated away and you will be left with:
my %policies = (
"abc" => "def",
"jfks+" => "jfk ",
"(d+)uu" => "uu1"
You need to use single quoted strings instead. Also, the back-reference
\1 is only valid *inside* a regular expression, not in a replacement string:
my %policies = (
'abc' => 'def',
'jfk\s+' => 'jfk ',
'(\d+)uu' => 'uu$1',
> #... many policies here
> );
>
> foreach (<DATA> )
> {
> s/$_/$policies{$_}/g for keys %policies;
You should use a while loop instead of a foreach loop to read from a
file. The current line is in the $_ variable. The substitution
modifies the $_ variable but it now contains one of the keys of
%policies and not the current line. You need to do something like this:
while ( my $line = <FILE> ) {
$line =~ s/$_/$policies{$_}/g for keys %policies;
Now, as to the use of back-references in the replacement string there
are some clues to be found at:
perldoc -q "How can I expand variables in text strings"
Which finally brings us to this:
while ( my $line = <FILE> ) {
$line =~ s/$_/qq{"$policies{$_}"}/eeg for keys %policies;
John
--
Perl isn't a toolbox, but a small machine shop where you
can special-order certain sorts of tools at low cost and
in short order. -- Larry Wall
| |
| Rob Dixon 2008-01-22, 8:09 am |
| Zhao, Bingfeng wrote:
> Hi list,
> I'm in trouble and hope who can work me out.
> I want to so some replacements, so I want to keep all replacement
> policies in a hash so that I can use them in a foreach loop, such as:
>
> my %policies = (
> "abc" => "def",
> "jfk\s+" => "jfk ",
> "(\d+)uu" => "uu\1"
> #... many policies here
> );
>
> foreach (<DATA> )
> {
> s/$_/$policies{$_}/g for keys %policies;
> print;
> }
>
> But perl complains, so I update it as:
> my %policies = (
> qr/abc/ => "def",
> qr/jfk\s+/ => "jfk ",
> qr/\d+uu/ => "uu\1"
> );
>
> foreach (<DATA> )
> {
> s/$_/$policies{$_}/g for keys %policies;
> print;
> }
>
> The result is wrong, since I got \1 instead of matched part. I update it
> again as:
> my %policies = (
> qr/abc/ => qr/def/,
> qr/jfk\s+/ => qr/jfk /,
> qr/\d+uu/ => qr/uu\1/
> );
>
> foreach (<DATA> )
> {
> s/$_/$policies{$_}/g for keys %policies;
> print;
> }
>
> Perl complains again that \1 is not refer to anything. So I try to put
> the whole s/// into a list:
> my $policies = (
> s/abc/def/g,
> s/jfk\s+/jfk /g,
> s/\d+uu/uu\1/g
> );
>
> foreach (<DATA> )
> {
> $_ =~ $_ for $policies;
> print;
> }
>
> It generates more errors. So my question, how can I save my replacement
> policies in perl data structure so that I can use it just as single one?
I suggest:
apply_policies($value);
sub apply_policies {
for ($_[0]) {
s/abc/def/;
s/jfk\s+/jfk /;
s/(\d+)uu/uu\1/;
}
}
HTH,
Rob
|
|
|
|
|