我确信可以使用split()
完成此操作,但如果可能,我更感兴趣的是使用s//
。我想比较提供的IP地址和IP地址数组,并找到匹配(如果存在)。我还想考虑只有整个元素(不是数组元素的子串)匹配才能成功部分匹配。
例如:提供的IP:10.12.13.14
如果当前数组元素是10.12。或10.或10.12.13。我们可以考虑匹配,但不是10.12.11。
这是为了查找Linux主机上的hosts.allow TCP包装文件中是否存在给定的IP。如果文件中没有包含地址,我将添加附加地址的功能。由于部分子网匹配10.120。或192.168。工作,我也需要测试那些。这是我在下面缺少占位符“OR SUBSTRING MATCHES”的代码。我想知道my $IP = "1.2.3.4";
如何创建子字符串变量,以便我可以在"1.2.3."
和"1.2."
上执行字符串比较?
#PSEUDO CODE EXAMPLE
my @IPS = (10.12.13.14, 191.168.1.2, 10.8., 172.16. );
my $IP = "10.8.3.44";
foreach (@IPS) { if( $IP eq $_ || split(/\d+\./, 1-3, $IP) eq $_ ) { print $IP matches current IP: $_\n}
# That split is supposed to represent "10." "10.8." and "10.8.3." That is the logic I am trying to accomplish, but I would like to use s// if it fits the job, otherwise I am open to split() or other suggestions
#REAL CODE EXAMPLE
#!/usr/bin/perl
my $IP = $ARGV[0];
my $FILE = '/etc/hosts.allow';
# Make sure it is an IP with either 157. or 140. as first octet
unless ( $IP =~ qr/(140|157)\.(\d{1,3}\.){2}\d{1,3}/ ) {
die "Usage: $0 IP Address" } else {
open (FH, "<", "$FILE");
foreach $LINE (<FH>) {
if ( $LINE =~ qr/^sshd: (.*)/i ) {
@LIST = split(", ", $1);
foreach (@LIST) {
chomp $_;
if($IP eq $_) || (OR SUBSTRING MATCHES ) <-need code here {
print "IP ADDRESS: $IP found! \n";
} else { print "$_ is not a match\n"};
}
}
}
}
答案 0 :(得分:1)
use strict;
use warnings;
use feature qw/say/;
use Net::Subnet;
my $allowed_hosts = subnet_matcher qw(
10.8.0.0/16
10.12.13.14/32
191.168.1.2/32
172.16.0.0/16
);
for my $ip (qw/10.8.3.44/) {
if ($allowed_hosts->($ip)) {
say "$ip is allowed!";
}
else {
say "$ip is disallowed!";
}
}
答案 1 :(得分:1)
您可以构建正则表达式以匹配您接受的列表。正如M42已经演示的那样,您需要使用quotemeta
,这样您的句号不会被视为任何字符。您还需要注意边界条件:
my @ips = qw(10.12.13.14 191.168.1.2 10.8. 172.16.);
my $ips_list = join '|', map {/\d$/ ? "$_\$" : $_} map quotemeta, @ips;
my $ips_re = qr{^(?:$ips_list)};
while (<DATA>) {
chomp;
if ($_ =~ $ips_re) {
print "(pass) $_\n";
} else {
print "(fail) $_\n";
}
}
__DATA__
10.8.3.44
999.10.8.999
10.12.13.14999
10.12.13.14
172.16.99.99
191.168.1.2
191.168.1.29
输出:
(pass) 10.8.3.44
(fail) 999.10.8.999
(fail) 10.12.13.14999
(pass) 10.12.13.14
(pass) 172.16.99.99
(pass) 191.168.1.2
(fail) 191.168.1.29
答案 2 :(得分:0)
怎么样:
if ( ($IP eq $_) || ($IP =~ /^\Q$_/) ) {