2017-10-21 98 views
3

想知道如果我能得到另一双眼睛在这个。排除数组,如果它包含字符串

用例;从区域文件中抓取DNS记录以运行shell_exec将其导入另一个平台。

我想从区域文件,记录,CNAME,TXT,MX等中获取所有类型的DNS记录。目前为止,我已经成功完成了CNAME,TXT和MX记录。

我被困在A记录上。不幸的是,当我搜索文件的每一行时,这导致CNAME和SOA也被返回。下面是我有:

// Looking for: 
$search_a = 'A'; 

// Read from file 
$lines = file("$domain."); 

// Check if the line contains A 
foreach($lines as $a) { 
    if(strpos($a, $search_a) !== false) { 
    $a_array = "$a"; 
    $a_record_output = preg_split('/(.'.$domain.'.|\s)/', $a_array, -1, PREG_SPLIT_NO_EMPTY); 
    print_r($a_record_output); 
    } 
} 

这将返回:

Array 
(
    [0] => domain.io. 
    [1] => SOA 
    [2] => ns1.domain.io. 
    [3] => stuff. 
    [4] => (64719 
    [5] => 14400 
    [6] => 7200 
    [7] => 2419200 
    [8] => 3600) 
) 
Array 
(
    [0] => domain.io. 
    [1] => A 
    [2] => 8.8.8.8 
) 
Array 
(
    [0] => autodiscover 
    [1] => CNAME 
    [2] => autodiscover.outlook.com. 
) 

显然,这是工作,但是,我需要排除的SOA和CNAME记录,因为我只是寻找一个记录。

我需要完全忽略CNAME和SOA阵列和只返回包含刚刚A.这里有一个从区域文件

domain.io.  A 8.8.8.8 
www    CNAME domain.io 

是否有这样做的方式提取的吗?

+1

区文件是制表符分隔的文件吗?像这样:example.com。 IN A 192.0.2。1 – bluehipy

+1

发布您的初始文件内容 – RomanPerekhrest

回答

1

您可以检查结果数组的第二个元素是否为A,并且仅当它是时,继续您的逻辑。否则,跳过该行:

if ($a_record_output[1] !== "A") continue; 

Demo

它很可能会更好但如果你没有选择的纪录所有,而不是过滤它们。您可以使用preg_match()用一个单词边界,而不是strpos()此:

if (preg_match("/\b".$search_a."\b/i", $a)) { 

Demo

+0

您的第二个版本似乎是我需要的完美。我甚至没有考虑将$ search_a添加到preg_match中。非常感谢你!为我节省了大量的时间! – Dan

0

如果你打算把你的文本文件导入阵列形式,你可以用preg_grep()过滤。这是使用preg_match()在循环中搜索的逻辑替代。

$search_a = 'A'; 
var_export(preg_grep('/^[^\t]+\t+'.$search_a.'\t/',file("$domain."))); 

这从各行的前面,一个或多个非制表符,那么一个或多个制表符,然后将针串,然后一个制表符,以确保我们正在紧张的比赛相匹配。

preg_quote()可能是必要的,具体取决于在$search中将使用哪些字符。

...有几种方法来剥皮这只猫。


p.s.你的preg_split()模式也可以使用一些改进。如果你从文件中提供原始文本,我可以为你制作一个更好的文本。

相关问题