如果数组包含字符串,则排除该数组

3
希望有人能帮我看看这个问题。应用场景:从区域文件中获取DNS记录,以便运行shell_exec将其导入到另一个平台。我试图获取所有类型的DNS记录,包括A记录、CNAME、TXT、MX等。目前我已经成功地获取了CNAME、TXT和MX记录。但是在获取A记录时却遇到了问题,因为当我搜索文件的每一行寻找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记录,因为我只搜索A记录。

我需要完全忽略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
2个回答

0

您可以检查结果数组的第二个元素是否为A,只有在它是的情况下,才能继续执行您的逻辑。否则,请跳过该行:

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

演示

如果您不选择记录而是过滤它们,可能会更好。您可以使用preg_match()和单词边界,而不是strpos()来实现这一点:

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

演示


你的第二个版本对我来说完美无缺。我甚至没有想到把$search_a添加到preg_match中。非常感谢你!省了我大量时间! - user3206138

0
如果您要将文本文件转换为数组形式,可以使用preg_grep()进行筛选。这是使用循环进行搜索的preg_match()的逻辑替代品。
$search_a = 'A';
var_export(preg_grep('/^[^\t]+\t+'.$search_a.'\t/',file("$domain.")));

这个正则表达式从每一行的开头匹配一个或多个非制表符字符,然后是一个或多个制表符字符,接着是针字符串,最后是一个制表符以确保我们进行了紧密匹配。

根据将在$search中使用哪些字符,可能需要使用preg_quote()函数。

...有几种方法可以解决这个问题。


顺便说一下,你的preg_split()模式也可以进行一些改进。如果你提供文件中的原始文本,我可以为你打造更好的模式。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接