ugrás a tartalomhoz

Reguláris kifejezés illeszkedjen sortörésre is

s_volenszki · 2007. Okt. 22. (H), 13.29
Sziasztok!

Meg szeretném kérdezni, ti már találkoztatok-e hasonló jelenséggel?

Egy könyvtárban van sok-sok kép, amik sajnos kis és nagy betűk összevisszaságából áll. Készítettem egy kis rutint, ami átnevezi azokat kisbetűssé. Ez idáig rendben van.

Most ott tartok, hogy egy másik rutin beolvassa a könyvtárban található összes html file-t, és preg_match_all eljárással kikeresi az összes img tag src attribútumát, majd kisbetűssé alakítja és kicseréli az eredeti pozícióban.

Ez a kód:

preg_match_all("/(<img .*?src.*?=.*?\")(.*?)(\".*?>)/", $file_tartalom, $eredmeny);
Az a gond, hogy az oldalakat azt hiszem Front Page-el szerkesztették, és valami halál hülye kód formázással tökéletesen széttördeli a html kódot, ezért e preg_match_all nem talál egyezőséget. Valahogy így:

...
    <tr>
        <td align="center"><font color="#FFFFFF" size="2"
        face="Arial"><img
        src="hegy.JPG"
        width="360" height="245"></font></td>
        <td align="center"><font color="#FFFFFF" size="2"
        face="Arial"><img
        src="mozaik.JPG"
        width="360" height="245"></font></td>
    </tr>
...
Van lehetőség arra, hogy a minta figyelmen kívül hagyja az adott tag-en belüli sortöréseket?

Vagy lehet olyan mintát készíteni, ami egy html tag-ben a kezdő < és a végződő > kacsacsőrök között, az összes sortörést kiszedi?

Gondoltam rá, hogy a file beolvasása közben kiszedek minden '\n' -t, de akkor tökéletesen összeomlik a html file formázottsága (már amit nem tesz tönkre a FP).

Válaszaitokat előre köszönöm, üdv
s_volenszki
 
1

s módosító

kicsy · 2007. Okt. 22. (H), 14.25
Az s módosító használhatával a . illeszkedik az újsor karakterre is:
/(<img .*?src.*?=.*?\")(.*?)(\".*?>)/s
Ugyanakkor a .*? részek nekem furák, a * nulla vagy több karakterre illeszkedik, tehát a ?-et ott már feleslegesnek érzem.
Érdemes még az U módosítót is használni, hogy a .*-ok ne zabálják be az utánuk következő részeket, vagy pl az src utáni .*-ot [^=]*-ra, az = utánit [^\"]*-ra cserélni (vagy méginkább \s*-ra) :
/(<img .*src\s*=\s*\")([^"]?)(\".*>)/is
2

mohó, nem mohó

Hodicska Gergely · 2007. Okt. 22. (H), 15.45
Ugyanakkor a .*? részek nekem furák, a * nulla vagy több karakterre illeszkedik, tehát a ?-et ott már feleslegesnek érzem.
Itt mást jelent a ?, mint amire gondolsz. Alap esetben a sokszorozó kvantorok mohók, ami azt jelenti, hogy a lehető legtöbb karakterre próbálnak meg illeszkedni. Ha mögéjük teszed a ?-et, akkor ezt a viselkedést változtatod meg. Pl. legyen a tárgyszöveg: "<img><img>", a "<img.*>" a teljes sy0vegre illeszkedik, míg a "<img.*?>" csak az első tagre.


Üdv,
Felhő
3

A kérdőjeles kvantor ugyanazt csinálja, mint az U módosító

Fraki · 2007. Okt. 22. (H), 16.42
A kérdőjeles kvantor ugyanazt csinálja, mint az U módosító globálisan.
5

Értem

kicsy · 2007. Okt. 23. (K), 01.05
Köszi, ezt nem tudtam - minden nap tanul valami újat az ember :)
8

Nem akarja az igazságot!

s_volenszki · 2007. Okt. 23. (K), 10.43
Szia!

Köszönöm a segítséget. Hozzá adtam az "s" módosítót, és valóban, minden sortörést értelmez, de csak azokat, amelyek a megtalálandó paraméter után találhatóak, azaz ha a soremelés az <img után található, akkor továbbra sem talál illeszkedést!

Végülis, ezt már tudom kezelni, mert megkerestetek a file-ban minden <img-t és ha a következő karakter kód 10, akkor azt kicserélem space-re.

Köszönöm a segítségeteket, üdv:
s_volenszki
4

kell regularis kifejezes?

toro · 2007. Okt. 22. (H), 22.25
en nem a regularis kifejezest csiszonam ebben az esetben:
strpos()-sal megkeresnem az src=" karaktersort, majd egy strtolower()-rel atirnam a legkozelebbi "-ig terjedo string szakaszt

tudom, hogy nem tul emelkedett megoldas, de gyorsan meglehetsz a koddal...
6

elsőre

lacy · 2007. Okt. 23. (K), 01.07
ez az első képre rendben is van..de mi van ugyanabban a htmlben található második képpel?:)
7

strpos()

toro · 2007. Okt. 23. (K), 08.00
hat van ugye egy masodik parametere az strpos()-nak, amit offsetnek neveznek. Ezt beallitod a korabban megtalalt zaro idezojelnek megfeleoen es ujra elinditod a fent leirt processzust es folytatod, amig az strpos() nem ad false-t.

Ezt itt most kb annyi ideig tartott leirni, mint magat a kodot :)
9

igaz

lacy · 2007. Okt. 23. (K), 15.31
igazad van, így is lehet. (én is kerülöm a reguláris kifejezéseket, ahol lehet..:)
10

...én is kerülöm a reguláris kifejezéseket...

s_volenszki · 2007. Okt. 23. (K), 15.50
Osztom a véleményedet, de én kizárólag azért, mert egyszerűen nem értem. Sokszor kerestem már doksit kezdőknek reguláris kifejezésekből, kaptam is ajánlásokat (tőletek itt a laboron), de számomra értelmezhetetlen!

Ne érts félre, nem vagyok szellemi fogyatékos, bármilyen, számomra ismeretlen programozái nyelveben összehozok egy rutint kb. fél óra altt, de ez még nem megy (na meg az assembler)!

Olvastam egyszer itt a weblaboron (innen hivatkozott egy cikkre a weblabor) ahol arról volt szó, ki hogyan tud programozást tanulni (sajna már nem tudom a hivatkozást). Én a "Hello world!" típus vagyok, és ehhez a tanulástechnikához megfelelő regexp doksit még nem találtam.

s_volenszki
11

szerintem hiba nem megtanulni

Hodicska Gergely · 2007. Okt. 23. (K), 18.31
Szerintem a regexp egy olyan eszköz, amit hiba nem megtanulni, annyira hasznos tud lenni bizonyos helyzetekben. Ha szeretnéd megtanulni, akkor ott van például a Reguláris kifejezések mesterfokon című könyv. Vagy például az egyik személyes kedvencem az Andrei Zmievski féle Regexp clinic, szerntem egy csodálatosan felépített előadás a reguláris kifejezésekről. Ezen kívül szerintem a PHP doksi megfelelő oldalán is az alapok elég jól le vannak írva, illetve a PHP Architectnek is volt egy 3 részes cikksorozata a témában, ami szintén elég jó volt.


Üdv,
Felhő
12

Köszönöm!

s_volenszki · 2007. Okt. 23. (K), 18.54
Már le is töltöttem, meg fogom nézni!

Én már régóta érzem a benne rejlő erőt, sokszor használtam is, de mindíg ti segítettetek!
Megküzdök ezzel is! Amennyire erőmből telik, és tudáséhségem igényli!

s_volenszki
13

nem kerulom a regularis kifejezeseket

toro · 2007. Okt. 23. (K), 21.50
en nem kerulom a regularis kifejezeseket, ha van idom, szivesen elmolyolok vele, de sokszor van ugy hogy az ember sokkal tobb energiat fektet egy gondolat megvalositasaba, mint amennyit az meger, es mondjuk egy feszesebbre szabott hatarido megenged.
Ugy ereztem, hogy most ilyen helyzet allt elo, azert javasoltam az alternativat.
14

Készen vagyok!

s_volenszki · 2007. Okt. 28. (V), 20.42
Sziasztok!

Elkészült a "remekmű" és sikeresen elvégezte a feladatát!

Megköszönve a segítségeteket, íme a kód! Felhő által ajánlott doksi alapján egy kicsit megvariáltam, a mintát, mert nekem valójában teljesen mindegy, hogy csak az src atributumban lévő szöveget konvertálom kisbetűssé, vagy az egész taget (<img...>). Igaz az alt-ok megsínylették, de amúgy is csak tőszavak voltak! :)

//az adott könyvtárban található összes bejegyzés beolvasása
$konyvtar_nev = ".";
$konyvtar  = opendir($konyvtar_nev);
while(false !== ($fajlnev = readdir($konyvtar)))
{
    //kisbetűssé alakítás
    $tiszta_kisbetu = strtolower($fajlnev);
    //ha volt benne nagybetű
    if($fajlnev != $tiszta_kisbetu)
    {
        //átnevezés
        rename($fajlnev, $tiszta_kisbetu);
    }
    //htm és html file-ok tömbösítése
    if(substr_count($tiszta_kisbetu,".htm") OR substr_count($tiszta_kisbetu,".html")){$html[] = $tiszta_kisbetu;}
}

//ha van mit feldolgozni
if(is_array($html))
{
    //htm és html file-ok egyesével
    foreach($html as $egy_file)
    {
        //nyissuk meg a htm file-t és olvassuk be a tartalmát a $tartalom változóba
        $munka_file = $egy_file;
        $file_kezelo = fopen($munka_file, "r");
        $tartalom = fread($file_kezelo, filesize($munka_file));
        fclose($file_kezelo);
        
        //keressünk benne img tag-eket
        preg_match_all("/<\/?(img)[^>]*\/?>/", $tartalom, $talalat);
        $tags = $talalat[0];
        
        //ha van mit feldolgozni
        if(is_array($tags))
        {
            //találatok feldolgozása egyesével
            foreach($tags as $tag)
            {
                $kisbetus_tag = strtolower($tag);
                //ha volt benne nagybetű akkor csere
                if($kisbetus_tag != $tag)
                {
                    $tartalom = str_replace($tag,$kisbetus_tag,$tartalom);
                }
            }
            //file felülírása
            $file_kezelo = fopen($munka_file, "w+");
            fwrite($file_kezelo,$tartalom);
            fclose($file_kezelo);
        }
    }
}
Mindenkinek köszönöm!

s_volenszki
15

Saját életedet megkönnyítendő

vbence · 2007. Okt. 29. (H), 11.17
... elgondolkodhatsz az alábbi írásmódon:
<?
preg_match_all('#</?(img)[^>]*/?>#', $tartalom, $talalat);
17

Ajjaj...

s_volenszki · 2007. Okt. 29. (H), 15.57
Tisztán látom, hogy mondani akarsz valamit de sajnos nem értem! Azt látom, hogy a te mintád lényegesen egyszerűbb, arra irányult az életem megkönnyítése?

Kíváncsian várom válaszodat, üdv
s_volenszki
19

Egyszerübb írásmód

vbence · 2007. Okt. 29. (H), 20.16
Egy részt arra gondolok, hogy ha a mintábvan szerepel a / akrakter, akkor célszerű mást választani határoló karakternek. Szintén a HTML regexelésével kapcsolatos (bár nálad most nem jelentkezik), hogy ha " idézőjel szerepel a kifejezésben, akkor '-ot hasznáhatunk a string körül.
16

file_get_contetnst, file_put_contents

Hodicska Gergely · 2007. Okt. 29. (H), 14.54
Ajánlom Neked a két tárgybeli függvényt, meg a glob is érdekes lehet.
Ezenkívül szerintem a kód második felét teljesen meg tudnád úszni
preg_replace és az e módosító használatával (preg_replace("/.../e",
"strtolower('\\1')", $content)).


Üdv,
Felhő

u.i.: Már tegnap küldtem volna, a szerver nem engedte át.
18

Húha!

s_volenszki · 2007. Okt. 29. (H), 16.00
Még nem olvastam a manualt file_get_contents és file_put_contents-el kapcsolatbna, de ha ez azt jelenti amire gondolok, akkor ez igen baró! A preg_replace-ről nem is beszélve!

El is kezdem átdolgozni a rutint ennek fényében!

Köszönöm a figyelmeteket,
s_volenszki