如何在PHP中解析固定宽度的文本文件?

如何在PHP中解析固定宽度的文本文件?,php,parsing,Php,Parsing,我有大量数据如下所示: PHHI GFSX MOS GUIDANCE 10/19/2012 1200 UTC FHR 24 36| 48 60| 72 84| 96 108|120 132|144 156|168 180|192 SAT 20| SUN 21| MON 22| TUE 23| WED 24| THU 25| FRI 26|SAT CLIMO N/X 66 80| 68 82| 66

我有大量数据如下所示:

 PHHI   GFSX MOS GUIDANCE  10/19/2012  1200 UTC                       
 FHR  24  36| 48  60| 72  84| 96 108|120 132|144 156|168 180|192      
      SAT 20| SUN 21| MON 22| TUE 23| WED 24| THU 25| FRI 26|SAT CLIMO
 N/X  66  80| 68  82| 66  82| 66  81| 66  80| 67  82| 67  81| 67999999
 TMP  69  79| 71  81| 69  80| 69  80| 69  79| 69  80| 70  80| 70      
 DPT  63  64| 66  63| 64  64| 65  64| 65  66| 66  68| 68  65| 66      
 WND  11  10| 10  12| 11   9|  9   8|  8   8|  8   8|  8   7|  7      
 P12   8   9| 11   9| 21  14| 20  10| 18  20| 28  28| 46  15| 32999999
 P24      14|     19|     14|     23|     19|     36|     40|      999
 Q12   0   0|  0   0|  0   0|  0   0|  0   0|  1   1|       |         
 Q24       0|      0|      0|      0|      0|      1|       |         

 PHJH   GFSX MOS GUIDANCE  10/19/2012  1200 UTC                       
 FHR  24  36| 48  60| 72  84| 96 108|120 132|144 156|168 180|192      
      SAT 20| SUN 21| MON 22| TUE 23| WED 24| THU 25| FRI 26|SAT CLIMO
 N/X 999  84|999  84|999  84|999  85|999  84|999  84|999  84|999999999
 TMP 999  83|999  82|999  83|999  83|999  83|999  83|999  83|999      
 ........etc
192      
SAT CLIMO
 67 999999
 70      
 66      
  7      
 32 999999
      999
我需要在PHP中处理它,以便将其放入MYSQL数据库

在第一行中,需要第一个单词(站点名称)和日期/时间。 第二行和第三行根本不需要。
|
字符不相关。 最后两列有问题:

192      
SAT CLIMO
 67999999
 70      
 66      
  7      
 32999999
      999
这些数字彼此接触,但实际上它们是两个独立的变量。它应该更像这样:

 PHHI   GFSX MOS GUIDANCE  10/19/2012  1200 UTC                       
 FHR  24  36| 48  60| 72  84| 96 108|120 132|144 156|168 180|192      
      SAT 20| SUN 21| MON 22| TUE 23| WED 24| THU 25| FRI 26|SAT CLIMO
 N/X  66  80| 68  82| 66  82| 66  81| 66  80| 67  82| 67  81| 67999999
 TMP  69  79| 71  81| 69  80| 69  80| 69  79| 69  80| 70  80| 70      
 DPT  63  64| 66  63| 64  64| 65  64| 65  66| 66  68| 68  65| 66      
 WND  11  10| 10  12| 11   9|  9   8|  8   8|  8   8|  8   7|  7      
 P12   8   9| 11   9| 21  14| 20  10| 18  20| 28  28| 46  15| 32999999
 P24      14|     19|     14|     23|     19|     36|     40|      999
 Q12   0   0|  0   0|  0   0|  0   0|  0   0|  1   1|       |         
 Q24       0|      0|      0|      0|      0|      1|       |         

 PHJH   GFSX MOS GUIDANCE  10/19/2012  1200 UTC                       
 FHR  24  36| 48  60| 72  84| 96 108|120 132|144 156|168 180|192      
      SAT 20| SUN 21| MON 22| TUE 23| WED 24| THU 25| FRI 26|SAT CLIMO
 N/X 999  84|999  84|999  84|999  85|999  84|999  84|999  84|999999999
 TMP 999  83|999  82|999  83|999  83|999  83|999  83|999  83|999      
 ........etc
192      
SAT CLIMO
 67 999999
 70      
 66      
  7      
 32 999999
      999
有关于如何解析这个的提示吗?是否有用于解析固定宽度数据的辅助函数

我会在这里使用函数。

我会在这里使用函数。

你可以试试

$file = "log.txt";
$list = $part = array();

foreach ( file($file) as $line ) {
    $line = trim($line);
    if (strpos($line, "|") === false) {
        continue;
    }
    $line = explode("|", $line) and $line = end($line);
    $list[] = substr($line, 0, 3) . " " . substr($line, 3);
}
var_dump($list);
输出

array
  0 => string '192 ' (length=4)
  1 => string 'SAT  CLIMO' (length=10)
  2 => string ' 67 999999' (length=10)
  3 => string ' 70 ' (length=4)
  4 => string ' 66 ' (length=4)
  5 => string '  7 ' (length=4)
  6 => string ' 32 999999' (length=10)
  7 => string '       999' (length=10)
  8 => string ' ' (length=1)
  9 => string ' ' (length=1)
  10 => string '192 ' (length=4)
  11 => string 'SAT  CLIMO' (length=10)
  12 => string '999 999999' (length=10)
  13 => string '999 ' (length=4)
你可以试试

$file = "log.txt";
$list = $part = array();

foreach ( file($file) as $line ) {
    $line = trim($line);
    if (strpos($line, "|") === false) {
        continue;
    }
    $line = explode("|", $line) and $line = end($line);
    $list[] = substr($line, 0, 3) . " " . substr($line, 3);
}
var_dump($list);
输出

array
  0 => string '192 ' (length=4)
  1 => string 'SAT  CLIMO' (length=10)
  2 => string ' 67 999999' (length=10)
  3 => string ' 70 ' (length=4)
  4 => string ' 66 ' (length=4)
  5 => string '  7 ' (length=4)
  6 => string ' 32 999999' (length=10)
  7 => string '       999' (length=10)
  8 => string ' ' (length=1)
  9 => string ' ' (length=1)
  10 => string '192 ' (length=4)
  11 => string 'SAT  CLIMO' (length=10)
  12 => string '999 999999' (length=10)
  13 => string '999 ' (length=4)

过去我使用substr()函数从特定字段获取数据:

例如:

//Index:

012345678

192      
SAT CLIMO
 67999999
 70      
 66      
  7      
 32999999
      999
对于第一个专栏,我会有如下内容:

while($line = fgets($file)){

    $column1 = substr($line, 0, 3);
    $column2 = substr($line, 3, 6);
}

// for the line 32999999, you get:
// $column1 = 32
// $column2 = 999999

您可以将这些索引设置为常量,并在开始时通过一些字符计数来处理这些索引,但这将解决数字同时运行的问题。

过去,我使用substr()函数从特定字段获取数据:

例如:

//Index:

012345678

192      
SAT CLIMO
 67999999
 70      
 66      
  7      
 32999999
      999
对于第一个专栏,我会有如下内容:

while($line = fgets($file)){

    $column1 = substr($line, 0, 3);
    $column2 = substr($line, 3, 6);
}

// for the line 32999999, you get:
// $column1 = 32
// $column2 = 999999

您可以将这些索引设置为常量,并在开始时通过一些字符计数来处理这些索引,但这将解决数字同时运行的问题。

这是O'Reilly PHP烹饪书中回答的一个经典PHP问题


substr
工作正常。然而,
unpack
是我最喜欢的,因为它在下面使用了C函数,而且速度更快。

这是O'Reilly PHP食谱中回答的一个经典PHP问题


substr
工作正常。然而,
unpack
是我的最爱,因为它在下面使用了C函数,而且速度更快。

固定宽度使解析变得超级容易,有什么问题吗?只需将其子串。固定宽度使其非常容易解析,有什么问题吗?只需将其子串。这不是解析数据的解决方案。它在分隔符上分裂。把柱子弄脏,它还能用。那不是合同。如上所述,为每个列指定列的开始和长度,并使用substr()。这不是解析固定数据的解决方案。它在分隔符上分裂。把柱子弄脏,它还能用。那不是合同。如上所述,为每列指定列的开始和长度,并使用substr()。