如果数组包含字符串则排除数组
Excluding array if it contains string
想知道我是否能得到另一双眼睛。
用例;从区域文件中抓取 DNS 记录以便 运行 shell_exec 将它们导入另一个平台。
我正在尝试从区域文件、A 记录、CNAME、TXT、MX 等中获取所有类型的 DNS 记录。到目前为止,我做得很好,我已经设法获取了 CNAME、TXT 和 MX 记录。
我卡在A记录上了。不幸的是,当我在文件的每一行中搜索 A 时,这导致 CNAME 和 SOA 也被 returned。这是我拥有的:
// 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);
}
}
这个returns:
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 数组,只需要 return 只包含 A 的数组。这是区域文件的摘录
domain.io. A 8.8.8.8
www CNAME domain.io
有办法吗?
您可以检查结果数组的第二个元素是否为 A
,如果是,则继续您的逻辑。否则,跳过该行:
if ($a_record_output[1] !== "A") continue;
如果你根本不 select 记录而不是过滤它们,可能会更好。您可以为此使用 preg_match()
with a word boundary rather than strpos()
:
if (preg_match("/\b".$search_a."\b/i", $a)) {
如果您打算将文本文件放入数组形式,您可以使用 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()
模式也可以使用一些改进。如果您提供文件中的原始文本,我可以为您制作一个更好的文本。
想知道我是否能得到另一双眼睛。
用例;从区域文件中抓取 DNS 记录以便 运行 shell_exec 将它们导入另一个平台。
我正在尝试从区域文件、A 记录、CNAME、TXT、MX 等中获取所有类型的 DNS 记录。到目前为止,我做得很好,我已经设法获取了 CNAME、TXT 和 MX 记录。
我卡在A记录上了。不幸的是,当我在文件的每一行中搜索 A 时,这导致 CNAME 和 SOA 也被 returned。这是我拥有的:
// 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);
}
}
这个returns:
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 数组,只需要 return 只包含 A 的数组。这是区域文件的摘录
domain.io. A 8.8.8.8
www CNAME domain.io
有办法吗?
您可以检查结果数组的第二个元素是否为 A
,如果是,则继续您的逻辑。否则,跳过该行:
if ($a_record_output[1] !== "A") continue;
如果你根本不 select 记录而不是过滤它们,可能会更好。您可以为此使用 preg_match()
with a word boundary rather than strpos()
:
if (preg_match("/\b".$search_a."\b/i", $a)) {
如果您打算将文本文件放入数组形式,您可以使用 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()
模式也可以使用一些改进。如果您提供文件中的原始文本,我可以为您制作一个更好的文本。