[PHP] string uit textbestand halen maar dan 4 regels verder

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • nl2dav
  • Registratie: Juni 2001
  • Laatst online: 13-09 14:07
Beetje vreemde onderwerpsbenaming maar ik weet even niet hoe ik het duidelijker moet samenvatten. Ik heb het volgende probleem, ik heb een textbestand zoals bijvoorbeeld "input.dat". Daarin zoek ik naar een string zoals bijv. 123456-00. Wat ik dan wil is dat dan de regel die dan 3 regels verder pas voorkomt dat die in een variabele terecht komt. Voorbeeld;

code:
1
2
3
4
dhgd dfhgdhg fjjhgfgd fryuryur 123456-00 yfuyrtuyt gjghhgk
erteye rytr yr ruyr uytutyut utyyutuyt tugjhfg jvjhfgjhg ghjg 
fhgfgh fhgf hgfhg fhg fhgf hf hf rtyrtytrytr fuyruyr fuyruyr guyt
erterte 3425 AW Amsterdam rtyryry qwqew sfdsfs ouiou uih


Wat dan de bedoeling is dat alsie "123456-00" tegenkomt dat de regelpointer dan 3 regels vooruit wordt gezet en dat dan DIE regel in een variabele terecht komt.

Ik heb nu dit;

PHP:
1
2
3
4
5
6
7
8
9
10
<?
$fe = fopen("Z:\\input.dat", "r");
while ($regel = fgets($fe, 2048)) {
    if (stristr($regel, "123456-00"))
    {
                $nr_regel = $regel;
    echo $nr_regel ;
    }
}
?>


Dan wordt nu dus de regel waarin 123456-00 voorkomt in een variabele gezet ($nr_regel) en vervolgens ge-echo't. Das allemaal leuk en aardig maar ik wil dus eigenlijk de regel in een variabele hebben die 3 regels verderop staat (met die postcode en plaats).

Wie kan me een duw in de goede richting hiermee geven? Ik kan het niet in een array pompen dat is het (een) probleem en de data is verder compleet random dus kan geen verdere positiebepaling doen.

* En ja ik heb meerdere uren op php.net gezeten om uit te vinden welke instructie(s) ik nodig heb ;)

[ Voor 15% gewijzigd door nl2dav op 26-07-2003 17:29 ]


Acties:
  • 0 Henk 'm!

  • supakeen
  • Registratie: December 2000
  • Laatst online: 09-09 14:42
Waarom zou je hem niet in een array kunnen inlezen :?

Acties:
  • 0 Henk 'm!

Verwijderd

Je kan toch gewoon op een \n een explode() uitvoeren???

Acties:
  • 0 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

PHP:
1
2
3
4
5
6
7
8
9
10
$linenumber = 0
while(..)
{
  if($linenumber  == 2)
  {
     ...
  }

  $linenumber++;
}


Btw, als je toch als file in leest en in een array kwakt, neem dan de functie file()...

?

[ Voor 34% gewijzigd door ACM op 25-07-2003 16:59 ]


Acties:
  • 0 Henk 'm!

  • supakeen
  • Registratie: December 2000
  • Laatst online: 09-09 14:42
Verwijderd schreef op 25 juli 2003 @ 16:57:
Je kan toch gewoon op een \n een explode() uitvoeren???
En dan met eregi in een loop kijken waar het gezochte nummer zit en dan het stukje array van vier regels verder pakken :)

Acties:
  • 0 Henk 'm!

  • RupS
  • Registratie: Februari 2001
  • Laatst online: 17-07 14:45
nl2dav schreef op 25 July 2003 @ 16:49 o.a.:
[..]
code:
1
2
3
4
5
6
7
8
9
10
<?
$fe = fopen("Z:\\input.dat", "r");
while ($regel = fgets($fe, 2048)) {
    if (stristr($regel, "123456-00"))
    {
                $nr_regel = $regel;
    echo $nr_regel ;
    }
}
?>

[..]
PHP:
1
2
3
4
5
6
7
8
9
10
11
$fe = fopen("Z:\\input.dat", "r");
$i = 4;
while ($regel = fgets($fe, 2048)) {
  $i++;
  if (stristr($regel, "123456-00")) {
    $i = 0;
  }
  if ($i == 3) {
    $nr_regel = $regel;
  }
}


Kan je het niet (ongeveer) op deze manier oplossen? Ik doe maar een gooi in een richting :)
Moet er wel reglmaat inzitten. Als je nu bijvoorbeeld na twee regels weer 123456-00 tegenkomt, mis je er 1.

edit:

Wat ACM _iets_ eerder zegt dus :)

[ Voor 10% gewijzigd door RupS op 25-07-2003 17:02 ]


Acties:
  • 0 Henk 'm!

  • nl2dav
  • Registratie: Juni 2001
  • Laatst online: 13-09 14:07
Omdat er allemaal nutteloze data tussendoor staat (DOS screendump) en dat het dan anders een ontzettend zooitje wordt? Er komt dan niet meer logica in, dan anders, mijns inziens?

* Probeert even wat ThaRups voorstelt

[ Voor 11% gewijzigd door nl2dav op 25-07-2003 17:03 ]


Acties:
  • 0 Henk 'm!

Verwijderd

PHP:
1
2
3
4
<?php
    $lines = file("input.dat");
    echo $lines[array_search("123456-00", $lines)+3];
?>

[ Voor 24% gewijzigd door Verwijderd op 25-07-2003 17:03 ]


Acties:
  • 0 Henk 'm!

  • ddofborg
  • Registratie: Augustus 2000
  • Laatst online: 06-05 19:28
je kunt gewoon de file scannen op "\n" of "\r\n" en als je daar 4 van hebt gevonden, dan moet je die regel 'echt' lezen, maar ik geloof dat er een funtie is die XXde regel van een file in kan lezen. readline(int) ofzo.

Acties:
  • 0 Henk 'm!

  • nl2dav
  • Registratie: Juni 2001
  • Laatst online: 13-09 14:07
Oke bedankt :), ik ben nog nooit zo snel geholpen. Wat ACM/ThaRups voorstelde is precies hetgene wat de bedoeling is, ik zal nog even kijken of de variant van Densetsu2 ook toepasbaar is en wat dan weer sneller/beter/compacter is maarrem ik ben blij met de hulp (wat ik wil werkt dus nu)!

Dank! _/-\o_

* Ehhmm 1 ding nog waarom wordt $i = 4 gezet? Dat hoeft toch niet?

[ Voor 12% gewijzigd door nl2dav op 25-07-2003 17:17 ]


Acties:
  • 0 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Denk dat hij je vraag anders begreep dan ik :)

hij doet de 4e regel NA je die code hebt gevonden, ownee, dat is wel wat je wilde?

[ Voor 49% gewijzigd door ACM op 25-07-2003 17:26 ]


Acties:
  • 0 Henk 'm!

  • nl2dav
  • Registratie: Juni 2001
  • Laatst online: 13-09 14:07
Hmmm hij start met $i op 4 te zetten en begint dan die while loop (bovendien komt er direct al $i +1 bij). Als die string gevonden wordt, word $i op nul gezet en dan begint er pas echt geteld te worden.

Het vooraf instellen van $i = 4 zou dan gewoon geen nut hebben of wel? Ik ben nog niet zo goed met PHP maar dacht wel dat het dit soort logica was :)
(edit, ben er net achter dat dat wel een doel heeft, maar begrijp het nog niet helemaal ;) )

Anyway ik heb toch een flinke tegenvaller. Dit grapje werkt wel, maar helaas wilde ik dit in een bestaande "while" gooien dus dat er een file uitgelezen wordt en tegelijkertijd deze andere file ook nog eens een keer. PHP is het niet helemaal eens met een "while" in een "while" geloof ik...

die array_search suggestie werkt trouwens ook niet, wordt totaal genegeerd. Waarschijnlijk omdat mijn bestand niet echt een array indeling is :/

[ Voor 8% gewijzigd door nl2dav op 26-07-2003 00:28 ]


Acties:
  • 0 Henk 'm!

  • RupS
  • Registratie: Februari 2001
  • Laatst online: 17-07 14:45
nl2dav schreef op 26 July 2003 @ 00:20:
Hmmm hij start met $i op 4 te zetten en begint dan die while loop (bovendien komt er direct al $i +1 bij). Als die string gevonden wordt, word $i op nul gezet en dan begint er pas echt geteld te worden.

[...]
:)

Ik zet $i in het begin op 4 omdat hij anders altijd na drie keer loopen al iets gaat doen. als $i op 0 begint en je doet binnen de loop $i++, dan zal zodra $i 3 is, je script al een regel uitspugen en dat wil je niet ;)

Vandaar dat ik hem op 4 zet, en pas zodra er een match is, $i gelijk zet aan 0 en er output gaat komen (Je geeft zelf eigenlijk al het antwoord)

Acties:
  • 0 Henk 'm!

  • nl2dav
  • Registratie: Juni 2001
  • Laatst online: 13-09 14:07
Oke ik kom er nog steeds niet helemaal uit, het principe werkt wel los van elkaar maar niet als ik "loops" ga "nesten" in elkaar. Ik heb mijn hele structuur ff kortgemaakt tot de kern van mijn huidige probleem.

De bedoeling is dat er uit een screendumpfile een nummer opgehaald wordt en in de andere file staat dit nummer ook maar dan met een woonplaats (continue 5 regels verder (vandaar nu $i=5))...

Nou giet ik die info in een mooie table (kuch) en wat krijg ik? Netjes alle nummers in een cel maar in de cel ernaast krijg ik alleen bij het eerste nummer de woonplaats die ik hebben wil. De opvolgende cellen blijven gewoon LEEG. Het lijkt wel of ie er gewoon mee kapt na een loop. Hoe kan dit?

Zoals je ziet heb ik de tweede nested while instructie vervangen voor een for instructie. Ik hoopte dat dit uitmaakte maar ik krijg precies hetzelfde resultaat als dat ik met de while instructie aan de gang ga. Hij stopt bij een loop.

Dit is de code die ik nu heb (zoveel mogelijk trachten in te korten);

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<table>
<?
$fd = fopen("nr.dat", "r");
$fe = fopen("nr_woonplaats.dat", "r");

while ($regel = fgets($fd, 2048) and ($regel2 = fgets($fd, 2048))) 
{
    if (stristr($regel, "Ŝ 0000"))
    {
    $pos = strpos($regel, "0000");
    $nr = substr($regel, $pos + 4, 9);
    ?>
    <tr>
    <td width="100" bgcolor="#FFFFFF"><? echo "$nr"; ?></td>
    <td width="300" bgcolor="#FFFFFF">
    <?
    for ($i=0; $regel3 = fgets($fe, 2048); $i++)
    {
        if (stristr($regel3, "$nr")) 
        { 
        $i = 0; 
        } 
        if ($i == 5) 
        { 
        $postcode_plaats = $regel3; 
        echo $postcode_plaats;
        } 
    }
    ?>
        </td>
</tr>
<?
    }
}
?>
</table>


Ohja nerver mind dat dubbel regel uitlezen van file1 ($fd), dat is noodzakelijk in m'n originele code...

Ik heb getracht met Google iets te weten te komen hoe het werkt met multiple while's / for's die genest zijn maar eehh zonder resultaat tot nog toe dus :/

*edit:

Google is nu ff sneller;
Support for `break' and `continue' statements inside loops
A script can break out of loop, or continue to the next iteration of the loop using "break" and "continue" statements. A special feature of PHP is the ability to specify an expression argument to break or continue, which specifies how many loops you want to break out from or continue to. For example:

for ($i=0; $i<10; $i++) {
for ($j=0; $j<10; $j++) {
if ($j>5)
break;
if ($i>5)
break 2;
}
}


The first break statement would end the inner loop every time $j is greater than 5. The second break statement would end both the inner and outer loop when $i is greater than 5.


In addition, switch statements are treated as loops. If you write "break 2;" inside a switch statement, you are asking to break out of the switch and the innermost loop in which it is nested.
Alleen snap ik nog niet helemaal hoe ik het moet toepassen. Dit in mijn for loop zetten bied wel enig resultaat :) ..;

PHP:
1
2
3
4
        if ($i > 15)
        {
        break;
        }


Oke maar niet voldoende dus, hij zoekt nu helemaal niet op nieuwe nr's meer, neemt alleen $nr eenmalig als referentie en telt vanuit daar gewoon steeds door :/

[ Voor 45% gewijzigd door nl2dav op 26-07-2003 17:29 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Wat ik zou doen als ik jou was, is alles wat overzichtelijker maken door niet alles ineens te willen doen. Eerst haal je de nummers op en je maakt een array met die nummers als key. Dat is deel 1, goed te overzien en te testen.

Dan maak je deel 2 waarin je de gegevens bij de nummers zoekt, die je dan dus in de array kan zetten bij de juiste keys. Weer een los overzichtelijk deel (wel het moeilijkste) wat goed te testen is

Daarna nog een laatste simpel deel dat de gemaakte array even in een tabelletje zet.

Dit is geen kant en klare oplossing voor je probleem maar slechts een aanpak die mij handig lijkt (maar ik snap niet alles helemaal, dus misschien kan het zo niet hoor?) Zo is het ook duidelijker te maken zodat je geen uur hoeft te kijken mocht je/iemand anders het ooit aanpassen.

Acties:
  • 0 Henk 'm!

  • nl2dav
  • Registratie: Juni 2001
  • Laatst online: 13-09 14:07
Nah, er zijn wat voorbeelden uit de search van dit forumonderdeel te halen zoals;

http://gathering.tweakers.net/forum/list_messages/257715
http://gathering.tweakers.net/forum/list_messages/55937
http://gathering.tweakers.net/forum/list_messages/196147


Waarbij link1 bv. precies hetzelfde is waar ik tegenaan loop maar ik krijg het maar niet opgelost [argh] 8)7 (staat ook geen oplossing daar grmbl)

Ik zal niet rusten voordat... ... :)

Het is ook vrij eenvoudig eigenlijk, nog even resumerend;

proces:
lees bestand1 uit per regel en filter het $nr uit de regel
indien $nr gevonden
lees bestand2 uit per regel totdat je $nr tegenkomt
sla vanaf daar 5 regels over en haal dan die regel eruit voor bewerking
einde proces bestand2
begin het hele proces van vooraf aan...

Ik begrijp echt niet dat ie alleen maar met het start $nr aan de slag gaat in bestand2.

---------
Laatste update:

Ik gebruik nu een MySQL database om de data te bufferen, dat was niet de bedoeling van mijn opzet en is h-e-l-e-m-a-a-l niet netjes (extra traag) maar leuke bijkomstigheid is dat ik nu extra functies kan uitvoeren (heb bedacht) daardoor.

Ik ben het er nog steeds niet mee eens dat het niet lukt op een dubbele while lus manier maarja... Misschien wordt ik later nog zo wijs om dat op te lossen :)

---------
Allerlaatste update:

Jaaaawwwellll, het werkt zoals het zou moeten. Het is echt belachelijk maar waar. Ik liep tegen een compleet ander probleem aan en was weer een beetje in de dubbele while loop situatie aan het klungelen geraakt. En ineens zag ik het licht :)

Die "$fe = fopen" regel moet binnen de eerste loop staan ipv dat je em een keer erbuiten opent. Vraag me niet waarom, ik denk om de file positie pointer te resetten of zoiets maar nu werkt het als een trein.

Ik heb het nu niet meer nodig omdat ik op de MySQL toer ben gegaan maargoed wilde toch nog ff een soort van oplossing neerkalken hier voor de archieven. Wie weet loopt er ook iemand tegenaan over 2 jaar :|

Werkende code voor de volledigheid;

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<table>
<?
$fd = fopen("nr.dat", "r");

while ($regel = fgets($fd, 2048) and ($regel2 = fgets($fd, 2048))) 
{
    if (stristr($regel, "Ŝ 0000"))
    {
    $pos = strpos($regel, "0000");
    $nr = substr($regel, $pos + 4, 9);
    ?>
    <tr>
    <td width="100" bgcolor="#FFFFFF"><? echo "$nr"; ?></td>
    <td width="300" bgcolor="#FFFFFF">
    <?
    $fe = fopen("nr_woonplaats.dat", "r");
    for ($i=0; $regel3 = fgets($fe, 2048); $i++)
    {
        if (stristr($regel3, "$nr")) 
        { 
        $i = 0; 
        } 
        if ($i == 5) 
        { 
        $postcode_plaats = $regel3; 
            if (stristr($postcode_plaats, "Ŝ ")) 
            {
            $postcode_plaats_bewerkt = substr($postcode_plaats, + 1, 36);
            echo $postcode_plaats_bewerkt;
            }
        } 
    }
    ?>
        </td>
</tr>
<?
    }
}
?>
</table>

[ Voor 90% gewijzigd door nl2dav op 27-07-2003 00:40 ]

Pagina: 1