Hozzászólások
Hello mindenkinek!
Van egy nagyon egyszerû kérdésem, nem vagyok még nagymenõ a C-ben:
Szeretnék egy olyan funkciót írni, ami beolvas egy fájlt, megkeres benne bizonyos stringeket és ezeket kicseréli valami másra.
Tudom, hogy ezt meg lehet csinálni egy bufferrel amibe fread-el beolvasom az egész fájlt, aztán úgy kezelem mint egy stringet. Regexp-el keresek, a cserére meg írni kell valamit.
Ezzel az a baj, hogy nagyobb fájlokban vagy ha keresett szövegrész hosszú és sokszor fordul elõ, elég lassú lehet.
Az fputs, frwrite, fputc stb. parancsokkal direkt módon írhatok a stream-be, viszont ezek fölülírják az adatokat adott pozición, ha a csere szöveg hosszabb mint a cserélni kívánt cucc.
Az lenne a kérdésem, hogy nincs-e erre más mód? Jó lenne a beolvasott buffert csak keresésre használni és a megfelelõ részeket a poziciók alapján kicserélni a fájlban.
Köszönöm!
Sziasztok
- A hozzászóláshoz be kell jelentkezni
1. open régi file
2. create tempfile
3. mindenféle keresés
4. találatig kiírás a tempbe
5. új szöveg kiírása tempbe
6. folytatás 3.-tól amíg file vége
...
7. tempfile átnevezése régi file-vé
Amúgy ha darabonként keresel, akkor a probléma az átlapolások hathatós kezelése... :-(
Zsiráf
- A hozzászóláshoz be kell jelentkezni
OK köszi szépen!
- A hozzászóláshoz be kell jelentkezni
Ok
kipróbáltam és tök jó, viszont most a keresésekkel van gond.
Egy szót vagy kifejezést szeretnék megkeresni, ami akár x helyen is szereplhet a fájlban.
A gondom a következõ:
Mind a PCRE regexp és a C lib beépített funkciói használnak egy tömböt, amibe elhelyezik a találatok elje / vége poziciókat. De sajnos ez ugye subexpression találatokra van kitalálva...-:( Az elsõ találat annak a stringnek a pozíciója, amely teljes egészében megfelelt a keresett mintának. A többi elvileg azoké amelyek csak részben feleltek meg.
De mi a helyzet akkor ha minden "subexpression" megfelel a teljes kifejezésnek?
A C libje ezt nem kezeli rendesen (valamelyik man page szerint), a PCRE kicsit más, de az eredmény ugyanaz.
Sajnos csak az elsõ pozicióját jegyzik fel, a többit pedig vagy meg se találják vagy minden pos azonos lesz.
Hogy lehetne ezt megoldani? Vagy ehhez nem is regexpet kéne használni, inkább maradjak az strstr és társainál? Attól tartok az nagyobb fájlok és sok keresés esetén jelentõsen lassíthat..
Ebben kérnék segítéset!
Köszi elõre!
Sziasztok
Bill
- A hozzászóláshoz be kell jelentkezni
Izé, lehet, hogy valami nem világos előtted :-)
A subexpression, nem azt jelenti, hogy részben felelt meg a mintának :-) hmm
nézzük a következő regexpet:
([a-z]+)[0-9a-z]*\.([0-9a-z]{0,3})
itt van egy regexp, ami vagy illeszkedik, vagy nem a stringedre! Nincs részben illeszkedés, azzal nem foglalkozik senki. Talált, vagy nem!!!
Viszon van benne 2 subexpression a két zárójeles () rész. Namost a tömböd 0 eleme azt adja meg, hogy a sztingedben mettől-meddig tart az egész regexp, az 1. eleme ugyanezt az első zárójeles részre, a második eleme a második zárójeles részre ... :-)
Zsiráf
- A hozzászóláshoz be kell jelentkezni
Köszi a választ. Jó rendben akkor ezt félreértettem kissé -:). Nekem akkor nem ez kell, de akkor most hogyan találhatom meg többször ugyanazt POSIX / PCRE regexpel?
A kifejezés csak egy szó, pl "provider" vagy ilyemsi.
Ha ezt simán keresem, akkor a pcre_exec csak egy találatot eredményez, holott 3 helyen is szerepel a fájlban. Ez ezek szerint így ok, hisz így subexpression nincs, tehát nem is tölti ki a tömböt.
De akkor most mivel lehetne megkeresni a többi pozicióját?
Az iHTML nyelvbõl indultam ki. Ott bármilyen kifejezést megtalál akárhányszor és a poziciók mennek egy listába. Ez lett volna jó C-ben is..-:)
- A hozzászóláshoz be kell jelentkezni
[quote:2d44313339="Anonymous"]A kifejezés csak egy szó, pl "provider" vagy ilyemsi.
Ha csak egy fix stringre keresel, akkor nem erdemes regexpet hasznalnod. Egy egyszeru strstr() megoldja a problemadat:
[code:1:2d44313339]char *buf; // ez amiben keresel
char *kincs; // ez az amit keresel
char *talalat; // ez mutatja a talalat helyet
while( (talalat=strstr(buf, kincs)) ) {
// kiirod a buf-tol talalatig terjedo reszt,
// kiirod a csere stringet
buf = talalat + strlen(kincs);
}
[/code:1:2d44313339]
Ennyi.
- A hozzászóláshoz be kell jelentkezni
Koszi szepen
Azota mar kitalaltam egy modszert PCRE-vel is, de ez sokkal egyszerubb.
Koszonom mindenkinek a segitseget.
- A hozzászóláshoz be kell jelentkezni