Performing a regex substitution Perl

2019-03-04 09:08发布

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

4条回答
我命由我不由天
2楼-- · 2019-03-04 09:39

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.

查看更多
叛逆
3楼-- · 2019-03-04 09:43

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
查看更多
Ridiculous、
4楼-- · 2019-03-04 09:57
$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;
查看更多
Juvenile、少年°
5楼-- · 2019-03-04 10:02

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.

查看更多
登录 后发表回答