2014-05-22 1 views
0

내가 아는 한/찾을 수있는 두 가지 방법이 있습니다.PHP에서 일반 텍스트 파일을 구문 분석하는 방법

  1. 상태 머신
  2. (
    Best way to parse a dynamic text list in PHP에 따라) 당신을 기반으로 레코드 (레코드 당 한 줄) 특정 규칙에 텍스트 파일을 감안할 때 줄 바꿈 explode("\n", $data)

에 폭발. 1에서 2까지의 문자는 yy 형식의 연도를 제공합니다. 3에서 4까지의 문자는 mm 형식으로 나타납니다. charachters 70에서 72는 x 매개 변수를 제공합니다.

CSV의 경우 우리는 str_getcsv()이지만 텍스트 파일에는 그런 것이 없다고 생각합니다.

내 개인적인 취향은 간단한 개행 옵션입니다. 생각?

텍스트 파일은 다음과 같다 : 각 레코드/라인

14 5 12466 3202313 710101010 31 7 9 5 3 4 4 4 4 50.21 
14 5 22466 41317 7 7 7 3 3 7 19 5 6 3 3 3 2 2 3 30.10 
14 5 32466 5 7 7 3 7 3172727 29 3 3 2 3 2 6 12 12 50.21 
14 5 42466 62337332330231713 60 9 22 18 9 15 9 6 5 120.73 
14 5 52466 71327202020202320 49 5 12 7 7 7 7 9 7 80.42 
14 5 62466 8 3 7 7 7 3 3 3 3 11 2 3 3 3 2 2 2 2 20.00 
14 5 72466 9 0 0 0 310 3 720 13 0 0 0 2 4 2 3 7 20.00 
14 5 82466102333334320333037 76 9 18 18 32 7 18 15 22 170.94 
14 5 924661130172017 7 3 010 31 15 6 7 6 3 2 0 4 50.21 
14 51024661220301310 7 32327 40 7 15 5 4 3 2 9 12 70.42 
14 5112466134330172713172027 58 32 15 6 12 5 6 7 12 120.73 
14 5122466142320202320101717 45 9 7 7 9 7 4 6 6 70.31 
14 51324661510131310 7 7 720 26 4 5 5 4 3 3 3 7 40.10 
14 5142466161710 3 72317 717 30 6 4 2 3 9 6 3 6 50.21 
14 51524661710101313 7101313 27 4 4 5 5 3 4 5 5 40.21 
14 5162466181713101020201710 35 6 5 4 4 7 7 6 4 50.21 
14 51724661913 7 3 7 3 3 3 3 13 5 3 2 3 2 2 2 2 30.00 
14 518246620171310 717201013 32 6 5 4 3 6 7 4 5 50.21 
14 5192466211013101013131020 30 4 5 4 4 5 5 4 7 50.21 
14 520246622 7 7101010 7 3 3 17 3 3 4 4 4 3 2 2 30.10 
14 521246623 7 3 3 3 0 3 3 7 9 3 2 2 2 0 2 2 3 20.00 
14 5222466241010109999999999  4 4 4  

몇 가지 규칙 :

1- 2 i2 yy, last two digits of year 
3- 4 i2 mm, month (1-12) 
5- 6 i2 dd, day of month (1-31) 

7-10 i4 Bartels solar rotation number - a sequence of 27-day 
intervals counted continuously from February 8, 1832 
11-12 i2 Number of day within the Bartels 27-day cycle 

13-28 8i2 3-hourly Kp indices (0-3, 3-6, 6-9, 9-12, 12-15, 
15-18, 18-21, 21-24 UT) 
29-31 i3 Daily Kp sum, expressed to the nearest third of a unit 
(supplied only for tradition, use Ap scientific 
purposes!) 

32-55 8i3 3-hourly ap indices (0-3, 3-6, 6-9, 9-12, 12-15, 
15-18, 18-21, 21-24 UT) 
56-58 i3 Ap equivalent daily amplitude - 
+0

귀하의 데이터가 귀하가 제안하는 것과 같이 규칙적이라면 정규 표현식을 사용해도 문제가 없을 것입니다. 편집 : 이제 정규식으로 간다 일부 샘플 데이터를 추가했습니다. –

+0

정규식이 필요 없습니다. 공간을 폭발 시키면 필요한 모든 필드가 있습니다. – Ikke

+1

fgetcsv()와 같은 함수를 사용하여 단락 문자를 단일 공백 ​​또는 '\ t'탭으로 바꿀 수 있습니다 –

답변

0

이 텍스트 형식은 어떤 구분을하지 않는 것 때문에 따로 줄 바꿈에서, 줄 단위로 읽어 들이고 substr을 사용하여 필드를 가져옵니다. 구분 기호가 없으므로 정규 표현식이나 CSV 독자는이 트릭을 수행하지 않습니다. 음, 정규 표현식은 기술적으로 가능합니다. 와일드 카드와 특정 반복 횟수를 지정할 수도 있기 때문에 결국에는 많은 가치를 추가하지 않습니다.

그러니 그냥 $line에 한 줄을 읽고, 문자의 수를 얻어서 그것을 구문 분석 :

$year = trim(substr($line, 0, 2)); 
$month = trim(substr($line, 2, 2)); 
// etc. 

그것은 성가신 보일 수 있습니다,하지만이처럼 깔끔한 기능이 포장 할 수 있습니다

$fields = array(
    'year' => array(0, 2, 'int'), 
    'month' => array(2, 2, 'int'), 
    'day' => array(4, 2, 'int'), 
    'hour' => array(6, 2, 'int'), 
    'amount' => array(8, 5, 'float') 
); 
:
function getIntField($line, $start, $length); 
{ 
    return (int)trim(substr($line, $start, $length)); 
} 

당신이 한 단계 더 걸릴 경우, 당신은 당신이 파일을 읽을 수 있도록 배열의 필드 정의를 만들 수 있습니다

그런 다음,이 같은 필드 읽을 수 있습니다 : 당신이 수업 시간에 이러한 기능을 포장하는 경우

function getField($line, $field) 
{ 
    $fields = .... field def goes here (or use global or class variable). 

    // Get the proper field definition for the field. (You can add some 
    // checking to see whether it exists. 
    $def = fields[$field]; 

    // Read the specified part (start, length are in the field definition). 
    $value = trim(substr($line, $def[0], $def[1])); 

    // In my example, the third parameter of the definition is the type. 
    switch ($def[2]) 
    { 
    case 'int': return (int)$value; 
    case 'float': return (float)$value; 
    } 

    // Not returned as a specific type? Then, just return the string. 
    return $value; 
} 

을, 다음은 파일 액세스를 처리하는 클래스가 매우 간단해야하고, 내부적으로 추적 현재 줄. 그럼 당신은 그냥이 같은 코드의 조각 작성할 수 있습니다

$amount = 0; 
$file = new FixedLengthRecordFile($filePath); 

while ($file->readLine()) 
{ 
    $amount += $file->getField('amount'); 
} 

echo 'Total amount in file: ' . $amount; 

원하는 경우를, 당신도 게터를 감싸는 마법 __get 방법을 사용할 수 있습니다. 그런 식으로, 당신은 쓸 수 있습니다 : 대신 어쨌든

$amount += $file->getField('amount'); 

$amount += $file->amount; 

, 즉 내가 이미 대한 것을 않는 아웃 - 오브 - 박스 클래스를 찾을 수없는 경우 내가 그것을 얼마나 아마 나를. 그러나 나는 거기 있다고 생각하지 않는다.

+0

그래, 이미'substr()'을 사용하기 시작했습니다. 그리고 여러분이 말했듯이, 정규식을 사용하는 것이 가능 합니다만, 문제는 그것이 가치있는 것인지 아닌지입니다. 지금 나는 타입에 관해서는 아무것도하지 않고있다. (문서가 그것에 대해 이야기한다.) 그래서 나는 당신이 제안한 것보다 더 단순하게 만들 것이다. 그러나 나는이 접근법을 좋아한다. –

관련 문제