如何从数组获取数据到变量

时间:2015-06-04 09:39:14

标签: php

我试图从使用file_get_contents创建的数组中获取数据。该文件是ADIF(* .adi),它是火腿无线电记录软件的输出,用于记录在火腿无线电上制作的联系人。

这是档案。

http://www.wildragon.com/StackOverflow.adi

我需要提取的是<" call:6">的值在这种情况下是ZL3DAC,这是我需要使用的值。 "调用"是工作站的呼号和" 6"是值中的字符数。

这是我正在使用的代码。

$fileToRead = // is defined earlier in the script.
function goBack() // is defined earlier in the script.

if (file_get_contents($fileToRead)) {
    echo "<br/>\nSuccess.";
} else {
    echo "<br/>\nFailed to read ADI.";
    goBack();
    die();
}
$array = explode("<EOR>", $x);
sscanf ($x, "<CALL:%d>%s ",$length,$rawcall);
$callsign = substr($rawcall,0,$length);
print_r($callsign);

我得到&#34;成功&#34;对于file_get_contents函数,但是我没有得到print_r的任何结果($ callsign);

请问我做错了什么,为了让这项工作成为现实,我需要做些什么?

1 个答案:

答案 0 :(得分:0)

为什么这不起作用的原因是因为sscanf()尝试匹配字符串的开头。因此,为了使用函数解析字符串,您必须首先使用一些简单的字符串操作。

获取要解析的文件的内容。

$contents = file_get_contents($file);

首先,我们使用strpos()搜索字符串'call:'的位置。 然后我们从找到的位置开始使用子串,并使用substr()转发。

$temporary = substr($contents, strpos($contents, 'call:'));

使用您提供的示例数据,临时变量具有 值:call:6>ZL3DAC <cont:2>OC <country:11>New Zealand...,直到数据字符串结束。

然后我们可以计算下一个开始标记的位置。这假设开始标记是不同数据的条目,因此我们应该超过我们想要的数据。

现在我们可以再次提取子字符串。该字符串应该只包含我们想要的数据。

$string = substr($temporary, 0, strpos($temporary, '<')); 

如果没有提供可选参数,sscanf()将返回一个数组,其中占位符的数量以相同的顺序定义。由于sscanf()要求将可选参数解析为引用,因此我使用list()来避免使用引用(引用不使用变量优化)。

list($length, $callsign) = sscanf($string, "call:%d>%s");

使用您提供的示例数据,变量$callsign包含ZL3DAC的值,变量$length包含6的值。

<强>替代

您还可以使用正则表达式。与其他任务相比,正则表达速度较慢,但​​由于我们必须事先做很多工作,所以我认为正则表达式在这里是可以接受的。这种解决方案的代码可以是。

$matches = [];
if(preg_match('~<call:(\d+)>(\w+)~', $contents, $matches) == false) {
    throw new \RuntimeException('Could not match callsign from input string.');
}

由于preg_match使用匹配的字符串填充$matches中的第一个元素,我们也会获得原始来源。然后我们可以将值提取到变量中。

使用原始字符串:

list($raw, $length, $callsign) = $matches;

没有原始字符串:

list($length, $callsign) = array_slice($matches, 1);

使用正则表达式获取多个值

您可以使用与上述相同的正则表达式使用正则表达式函数preg_match_all()。您还需要添加标志PREG_SET_ORDER以更轻松地提取结果集。使用this示例数据的示例可能是:

$matches = [];
preg_match_all('~<call:(\d+)>(\w+)~', $str, $matches, PREG_SET_ORDER);

这将导致$matches包含一个数组:

array (size=3)
  0 => 
    array (size=3)
      0 => string '<call:10>ZL100ANZAC' (length=19)
      1 => string '10' (length=2)
      2 => string 'ZL100ANZAC' (length=10)
  1 => 
    array (size=3)
      0 => string '<call:5>H44MS' (length=13)
      1 => string '5' (length=1)
      2 => string 'H44MS' (length=5)
  2 => 
    array (size=3)
      0 => string '<call:6>SV9CVY' (length=14)
      1 => string '6' (length=1)
      2 => string 'SV9CVY' (length=6)

第一个元素是原始匹配字符串。第二个是呼号的长度,第三个是呼号本身。

快乐的编码!