简体   繁体   中英

Performing a regex substitution Perl

Assuming I have the IP 10.23.233.34 I would like to simply swap the 233 for 234 . The first, second, and last octet are unknown. The third octet is either 233 or 234 . I want to do the substitution such that it matches the IP, subs, and keeps everything else while still switching the last octet. For example:

Input: 10.23.233.34

s/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){}233\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){}234\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/

Output: 10.23.234.34

This problem really isn't suited well for a regex solution. Instead, I would do something like the following:

$in = "10.23.233.34";
@a = split /\./, $in;
if ($a[2] == '233') {
    $a[2] = '234';
}
print join(".", @a);

The above code is far more readable than any regex you might come up with. Furthermore, the next person who has to maintain your code will be able to actually read it.

Sometimes regexes make things brittle and harder to understand. Nonetheless:

my $ip = '10.23.233.34';
...
for ($ip) {
    s!(?<=\.)233(?=\.\d+$)!234!;
}

Details: If given a well-formed dotted quad, the above looks for '233' in what must be the third octet: preceded by a dot and followed by a dot, then one or more digits, then end-of-string. The ?<= and ?= prevent anything other than the '233' from being captured, and then '234' is substituted. This approach does not validate that the IP address is well-formed.

$byte = qr/(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])/;
s/($byte)\.($byte)\.(23[34])\.($byte)/join '.', $1, $2, 467-$3, $4/e;

Here's an option:

use strict;
use warnings;

my $ip = '10.23.233.34';

$ip =~ s/(\d+)(\.\d+)$/($1 == 233 ? $1+1 : $1) . $2/e;

print $ip;

Output:

10.23.234.34

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM