搜索正则表达式来匹配/etc/hosts 中给定 IP 的 IP 和所有主机
主机文件示例:
10.10.10.10 test.com test2.com
10.10.10.11 test1.com
10.10.10.12 test3.com test5.com
使用的正则表达式:
^(\s+)?(?<Address>[0-9.:]+)(\s+(?<Host>[\w.-]+))+$
预期输出:
Address: ["10.10.10.10"]
Host: ["test.com","test2.com"]
Address: ["10.10.10.11"]
Host: ["test1.com"]
Address: ["10.10.10.12"]
Host: ["test3.com","test5.com"]
示例代码:
use strict;
use Data::Dumper;
my @str = ( "10.10.10.10 test.com test2.com",
"10.10.10.11 test1.com",
"10.10.10.12 test3.com test5.com");
foreach ( @str )
{
while ($_ =~ m/^(\s+)?(?<Address>[0-9.:]+)(\s+(?<Host>[\w.-]+))+$/img) {
print Dumper(\%+) ;
}
}
最佳答案
由于其中任何一个都不能有空格,并且地址始终排在第一位,因此可以简单地捕获所有非空格序列
my ($address, @hosts) = /(\S+)/g;
然后将它们放置在合适的数据结构中,例如
use warnings;
use strict;
use feature 'say';
use Data::Dumper;
my @str = (
"10.10.10.10 test.com test2.com",
"10.10.10.11 test1.com",
"10.10.10.12 test3.com test5.com" );
my %host;
foreach (@str) {
my ($address, @hosts) = /(\S+)/g;
$host{$address} = \@hosts;
}
say Dumper \%host;
至于问题中的尝试,该正则表达式有一个地址模式,然后有一个 URL 模式,并且它匹配一个地址和一个主机(尽管尝试匹配多个)主机)。
在该 while
循环的下一次迭代中,它继续尝试从第一次迭代中匹配的第一个主机之后进行匹配,并且在字符串中没有看到前面的地址,因此失败。这样我们就得到了一个地址和一台主机。 (为什么不显示输出呢?)
为了使该模式匹配多个主机(在地址之后),必须使这些量词(+
或更确切地说 *
)恰到好处,以便允许失败匹配,以一种非常不直观的方式。
此外,按照目前的模式,没有理由使用 while
循环,因为该模式旨在一次匹配所有内容。
另一种方法是使用 \G
来解析字符串,如果您的字符串中包含以任意顺序混合的感兴趣的项目,那么这种方法会比较合适。
虽然所有这些都是合法的,但这里使用的方式要简单得多(实际上只是变相的分割
)。
关于regex - Perl正则表达式匹配来自/etc/hosts的ip和host,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73944578/