ip address substitution

I propose the following code will properly take the variable $read_line
and substitute $new_ip_address for all occurrences of $old_ip_address.
Basically the snippet of code is from some software that will update a
set of old ip addresses with new ip addresses within a file. Can anyone
find any fault in it or see if I overlooked something, please? Of
particular concern is if I've considered enough by wrapping my
substitution string within (\D*)

$old_ip_address = "1.2.3.4";
$new_ip_address = "5.6.7.8"
$old_ip_address_regexp = $old_ip_address;
$old_ip_address_regexp =~ s/\./\\./ig;
$read_line =~ s/(\D*)$old_ip_address_regexp(\D*)/$1$new_ip_address$2/ig;

Thanks,
Jim

--
To unsubscribe, e-mail: beginners-unsubscribe [at] perl.org
For additional commands, e-mail: beginners-help [at] perl.org
http://learn.perl.org/
Jim [ Mi, 16 März 2011 15:29 ] [ ID #2056657 ]

Re: ip address substitution

--00151747ba0e27a57e049e9aa6db
Content-Type: text/plain; charset=ISO-8859-1

Assuming you are using strict and warnings,

Use quotemeta or \Q\E[0] instead of trying to escape things manually... Your
sanity will thank you.
And yes, the \D* could be troublesome; it depends on the text you are
matching against! For instance, 1.2.3.4.5 is not a valid IP, but you'd match
and replace part of it anyway. There's a great section about this on
Mastering Regular Expressions[1], "5.2.2. Matching an IP Address" and
"5.2.2.1. Know your context".

my $old_ip_address = "1.2.3.4";
my $new_ip_address = "5.6.7.8"
$read_line =~ s/
(?<![\w.]) #No alphanumeric or
period before the IP
\Q$old_ip_address_regexp\E #Quotemeta instead of trying to do
things by hand
(?![\w.]) #No alphanumeric or
period after the IP
/$new_ip_address/xg; #No need for $1 and $2, as we don't capture
anything.

Brian.


[0] http://perldoc.perl.org/functions/quotemeta.html
[1] http://regex.info/

--00151747ba0e27a57e049e9aa6db--
Brian Fraser [ Mi, 16 März 2011 15:49 ] [ ID #2056658 ]

Re: ip address substitution

On 11-03-16 10:29 AM, Jim wrote:
> $old_ip_address_regexp = $old_ip_address;
> $old_ip_address_regexp =~ s/\./\\./ig;

$old_ip_address_regexp = quotemeta( $old_ip_address );

See `perldoc -f quotemeta`.


--
Just my 0.00000002 million dollars worth,
Shawn

Confusion is the first step of understanding.

Programming is as much about organization and communication
as it is about coding.

The secret to great software: Fail early & often.

Eliminate software piracy: use only FLOSS.

--
To unsubscribe, e-mail: beginners-unsubscribe [at] perl.org
For additional commands, e-mail: beginners-help [at] perl.org
http://learn.perl.org/
Shawn H Corey [ Mi, 16 März 2011 15:49 ] [ ID #2056659 ]

Re: ip address substitution

Jim wrote:
> I propose the following code will properly take the variable $read_line
> and substitute $new_ip_address for all occurrences of $old_ip_address.
> Basically the snippet of code is from some software that will update a
> set of old ip addresses with new ip addresses within a file. Can anyone
> find any fault in it or see if I overlooked something, please? Of
> particular concern is if I've considered enough by wrapping my
> substitution string within (\D*)
>
> $old_ip_address = "1.2.3.4";
> $new_ip_address = "5.6.7.8"
> $old_ip_address_regexp = $old_ip_address;
> $old_ip_address_regexp =~ s/\./\\./ig;
> $read_line =~ s/(\D*)$old_ip_address_regexp(\D*)/$1$new_ip_address$2/ig;

(\D*) won't work because it can match zero characters. Just use (\D)



John
--
Any intelligent fool can make things bigger and
more complex... It takes a touch of genius -
and a lot of courage to move in the opposite
direction. -- Albert Einstein

--
To unsubscribe, e-mail: beginners-unsubscribe [at] perl.org
For additional commands, e-mail: beginners-help [at] perl.org
http://learn.perl.org/
jwkrahn [ Mi, 16 März 2011 16:05 ] [ ID #2056661 ]

Re: ip address substitution

On 11-03-16 11:05 AM, John W. Krahn wrote:
> Jim wrote:
>> $old_ip_address = "1.2.3.4";
>> $new_ip_address = "5.6.7.8"
>> $old_ip_address_regexp = $old_ip_address;
>> $old_ip_address_regexp =~ s/\./\\./ig;
>> $read_line =~ s/(\D*)$old_ip_address_regexp(\D*)/$1$new_ip_address$2/ig;
>
> (\D*) won't work because it can match zero characters. Just use (\D)

Use /(\D|^)$old_ip_address_regexp(\D|$)/


--
Just my 0.00000002 million dollars worth,
Shawn

Confusion is the first step of understanding.

Programming is as much about organization and communication
as it is about coding.

The secret to great software: Fail early & often.

Eliminate software piracy: use only FLOSS.

--
To unsubscribe, e-mail: beginners-unsubscribe [at] perl.org
For additional commands, e-mail: beginners-help [at] perl.org
http://learn.perl.org/
Shawn H Corey [ Mi, 16 März 2011 16:08 ] [ ID #2056663 ]

Re: ip address substitution

On 3/16/2011 10:49 AM, Brian Fraser wrote:
> Assuming you are using strict and warnings,
>
> Use quotemeta or \Q\E[0] instead of trying to escape things manually... Your
> sanity will thank you.
> And yes, the \D* could be troublesome; it depends on the text you are
> matching against! For instance, 1.2.3.4.5 is not a valid IP, but you'd match
> and replace part of it anyway. There's a great section about this on
> Mastering Regular Expressions[1], "5.2.2. Matching an IP Address" and
> "5.2.2.1. Know your context".
>
> my $old_ip_address = "1.2.3.4";
> my $new_ip_address = "5.6.7.8"
> $read_line =~ s/
> (?<![\w.]) #No alphanumeric or
> period before the IP
> \Q$old_ip_address_regexp\E #Quotemeta instead of trying to do
> things by hand
> (?![\w.]) #No alphanumeric or
> period after the IP
> /$new_ip_address/xg; #No need for $1 and $2, as we don't capture
> anything.
>
> Brian.
>
>
> [0] http://perldoc.perl.org/functions/quotemeta.html
> [1] http://regex.info/
>

It's possible there could be an alphabet character before the ip address
as in:
-s1.2.3.4

So given that possibility, would this be correct:
$read_line =~
s/(?<![\d.])\Q$old_ip_address_regexp\E(?![\d.])/$new_ip_address/g;

Can you explain:
?<!
?!

I was trying to find explanations of them, but they are difficult to
search on.

What is the purpose of the 'x' modifier assuming that is with regard to
ignoring whitespace. Was that included because of the format in which
you provided your example... broken across lines and additional whitespace?

I chose to drop it in my rewrite assuming that is true.

Thanks,
Jim

--
To unsubscribe, e-mail: beginners-unsubscribe [at] perl.org
For additional commands, e-mail: beginners-help [at] perl.org
http://learn.perl.org/
Jim [ Mi, 16 März 2011 18:09 ] [ ID #2056677 ]

Re: ip address substitution

--002354530970f9771e049e9e0892
Content-Type: text/plain; charset=ISO-8859-1

/x does exactly what you think it does; It's "free form" style, where any
non-escaped whitespace is ignored. See perlretut[0], perlop[1], and
perlre[2].

(?<!) is a negative lookbehind; (?!) is a negative lookahead. Meanwhile,
(?<=) is a positive lookbehind, and (?=) is a positive lookahead; They are
all explained in perlre, under Extended Patterns[3] (as well as in Mastering
Regular Expressions and Programming Perl). A look behind says that "this
pattern must match in the text before the position I'm currently in", while
a lookahead says the same, but for the positions further ahead in the
string. They are zero-width assertions like ^ and \b; In fact, \b translates
to (?:(?<=\w)(?!\w)|(?<!\w)(?=\w)), which admittedly is a mouthful.

Your regex should work fine I think, though if you want to be redundant you
could change \d to \p{PosixDigit}, not because it's really needed, but
mostly because Unicode character properties[4] are awesome.

Brian.

[0] http://perldoc.perl.org/perlretut.html
[1] http://perldoc.perl.org/perlop.html#Regexp-Quote-Like-Operat ors
[2] http://perldoc.perl.org/perlre.html#Modifiers
[3] http://perldoc.perl.org/perlre.html#Extended-Patterns
[4] http://perldoc.perl.org/perluniprops.html

--002354530970f9771e049e9e0892--
Brian Fraser [ Mi, 16 März 2011 19:51 ] [ ID #2056680 ]

Re: ip address substitution

On 16/03/2011 15:08, Shawn H Corey wrote:
> On 11-03-16 11:05 AM, John W. Krahn wrote:
>> Jim wrote:
>>> $old_ip_address = "1.2.3.4";
>>> $new_ip_address = "5.6.7.8"
>>> $old_ip_address_regexp = $old_ip_address;
>>> $old_ip_address_regexp =~ s/\./\\./ig;
>>> $read_line =~ s/(\D*)$old_ip_address_regexp(\D*)/$1$new_ip_address$2/ig;
>>
>> (\D*) won't work because it can match zero characters. Just use (\D)
>
> Use /(\D|^)$old_ip_address_regexp(\D|$)/

(?<!\d) and (?!\d) also match at the ends of a string, so

/(?<!\d)\Q$old_ip_address_regexp\E(?!\d)/

Rob

--
To unsubscribe, e-mail: beginners-unsubscribe [at] perl.org
For additional commands, e-mail: beginners-help [at] perl.org
http://learn.perl.org/
Rob Dixon [ Do, 17 März 2011 20:15 ] [ ID #2056740 ]
Perl » gmane.comp.lang.perl.beginners » ip address substitution

Vorheriges Thema: input file
Nächstes Thema: Read/Write XML file