我试图从使用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);
请问我做错了什么,为了让这项工作成为现实,我需要做些什么?
答案 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)
第一个元素是原始匹配字符串。第二个是呼号的长度,第三个是呼号本身。
快乐的编码!