php sscanf无法正确解析字符串

php sscanf无法正确解析字符串,php,parsing,scanf,adif,Php,Parsing,Scanf,Adif,我开发了ADIF解析器,解析过程达到了使用sscanf()php函数的程度。我解析的字符串如下:“QSO_日期:8:D>20070909”,我需要从这里提取如下信息:“QSO_日期”,“8”,“20070909”,所以我使用代码: sscanf("QSO_DATE:8:D>20070909", "%s:%d:D>%d") 但返回的数组如下所示: Array ( [0] => QSO_DATE:8:D>20070909 [1] =>

我开发了ADIF解析器,解析过程达到了使用sscanf()php函数的程度。我解析的字符串如下:“QSO_日期:8:D>20070909”,我需要从这里提取如下信息:“QSO_日期”,“8”,“20070909”,所以我使用代码:

sscanf("QSO_DATE:8:D>20070909", "%s:%d:D>%d")
但返回的数组如下所示:

    Array
(
    [0] => QSO_DATE:8:D>20070909
    [1] => 
    [2] => 
)
怎么了?也许有更有效的方法来解析一堆记录,如下所示:

<CALL:7>EM200FT<QSO_DATE:8:D>20140324<TIME_ON:4>1657<BAND:3>12M<MODE:5>PSK63<RST_SENT:3>599<RST_RCVD:0><QSL_SENT:1>Y<QSL_SENT_VIA:1>E<APP_EQSL_AG:1>Y<GRIDSQUARE:6>KN45kj<EOR>
<CALL:5>9V1SV<QSO_DATE:8:D>20140328<TIME_ON:4>1019<BAND:3>10M<MODE:4>JT65<RST_SENT:6>VK4CMV<RST_RCVD:0><QSL_SENT:1>Y<QSL_SENT_VIA:1>E<QSLMSG:54>Thank you and I confirm your SWL report, 73's de Siva.<APP_EQSL_AG:1>Y<GRIDSQUARE:6>OJ11ui<EOR>
<CALL:5>RA6DQ<QSO_DATE:8:D>20140328<TIME_ON:4>1019<BAND:3>10M<MODE:4>JT65<RST_SENT:3>599<RST_RCVD:0><QSL_SENT:1>Y<QSL_SENT_VIA:1>E<QSLMSG:3>73!<APP_EQSL_AG:1>Y<GRIDSQUARE:6>KN85nf<EOR>
EM200FT20140324165712MPSK63599YEKN45KJ
9V1SV20140328101910MJT65VK4CMVYE谢谢您,我确认您的SWL报告,73’s de Siva.YOJ11ui
RA6DQ20140328101910MJT65599YE73!YKN85nf

%s
表示任何字符,包括冒号、数字、V形符号等(除空格字符外),sscanf使用贪婪抓取。。。。使用更精确的替代方法,如
%[A-Z!]
%[^:]
可能比
%s
更好

$result = sscanf("QSO_DATE:8:D>20070909", "%[^:]:%d:D>%d");
var_dump($result);

它使用
%[^::]
扫描除
以外的任何字符:

谢谢!这很有效。这里还有一个问题:如何使“:D”部分可选?我的意思是让QSO_DATE:8:D>20070909用与“TIME_ON:4>1349”相同的代码进行解析?没关系,刚刚提出了解决方案:“[^::]:%D%[:>D]%s”现在这个诡计有问题了吗?它有点不同,但直接相关。问题是,我在以下方面有相同的模式:
sscanf('CALL:6>DO4HII','%[^:::%d%[:>d]%[^[[]]”)sscanf('QSO_日期:8:d>20070922','%[^:::::%d%[:d>]%[^[]])
第一个返回
Array([0]=>CALL 6[2]=>d[3]=>O4HII)
第二个
Array([0]>QSO[1]=>d]>200923]>
但我需要在第一个返回
数组中([0]=>调用[1]=>6[2]=>[3]=>DO4HII)
到底怎么做?你不能使用相同的模式,因为在数字
6
之间没有一个
,因此,您需要根据我最初的问题修改模式-是否可以执行“D”选项?那么,还有其他方法可以达到这个目标吗?因为我需要使用一个函数来解析所有这些字符串。