/ Forside / Teknologi / Udvikling / PHP / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
PHP
#NavnPoint
rfh 3959
natmaden 3372
poul_from 3310
funbreak 2700
stone47 2230
Jin2k 1960
Angband 1743
Bjerner 1249
refi 1185
10  Interkril.. 1146
Reg exp til at fjerne html.
Fra : Peter Anskjær


Dato : 05-03-05 01:15

Hej Ng
Jeg har en funktion der tager en html-fil og fjerner alt overflødig kode i
forhold til indsættelse på anden side, dvs. det er kun indholdet imellem
<body> og </body> der overlever. Jeg har lavet hele dokumentet om til små
bogstaver til at starte med for at undgå case-sensitivitet. Lige nu gør jeg
det med tre søgninger, først søger jeg efter <body, derefter søger jeg efter
> med resultatet fra første søgning som offset. Til sidst søger jeg efter
</body og tager en substring ud med passende start og slut.

Men nu er min tanke om man ikke kan lave det med noget preg_replace hvor
replacement er "". Jeg har leget lidt med det, men kan ikke få det til at
virke da jeg ikke er voldsomt gode venner med reg exp's.
Så er der nogen der kan give mig et hint til hvordan det kan gøres, kan det
i det hele taget svare sig i forhold til min nuværende løsning.

Det skal lige siges at jeg indtil videre ikke har kunne se nogle problemer
med min metode så længe det er nogenlunde korrekt html filen består af.

$htmllower = strtolower($html);
$startpos = strpos($html, ">", $bodypos = strpos($htmllower, "<body")) + 1;
$endpos = strpos($htmllower, "</body");
if($startpos != 1 || $bodypos != false)
$cleanhtml = trim(substr($html, $startpos, $endpos - $startpos));


Mvh
Peter



 
 
Peter Brodersen (05-03-2005)
Kommentar
Fra : Peter Brodersen


Dato : 05-03-05 01:22

On Sat, 5 Mar 2005 01:15:12 +0100, "Peter Anskjær"
<peter@_fjern_dette_nskjaer.dk> wrote:

>Men nu er min tanke om man ikke kan lave det med noget preg_replace hvor
>replacement er "".

$html =
preg_replace('#^(.*)<body(\s+.*?)?>(.*)</body\s*>.*$#si','$3',$html);

Så har du kun indholdet mellem <body> og </body> tilbage

--
- Peter Brodersen

Thomas Lindgaard (05-03-2005)
Kommentar
Fra : Thomas Lindgaard


Dato : 05-03-05 11:31

On Sat, 05 Mar 2005 01:21:51 +0100, Peter Brodersen wrote:

> preg_replace('#^(.*)<body(\s+.*?)?>(.*)</body\s*>.*$#si','$3',$html);
^

Hvorfor har du et ? inde i parentesen også?

--
Mvh.
/Thomas


Peter Brodersen (05-03-2005)
Kommentar
Fra : Peter Brodersen


Dato : 05-03-05 15:12

On Sat, 05 Mar 2005 11:30:39 +0100, Thomas Lindgaard
<thomas@it-snedkeren.BLACK_HOLE.dk> wrote:

>> preg_replace('#^(.*)<body(\s+.*?)?>(.*)</body\s*>.*$#si','$3',$html);
> ^

(\s+.*?) er for at matche eventuelle parametere. En anden mulighed
ville være [^>]* - derimod kan man godt rette \s+ til \s.

..*? er et lazy match, dvs. den matcher så kort som muligt indtil det
næste tegn. Husk, at .* jo også matcher tegnet ">", så hvis jeg blot
brugte .*, så ville den matche ud over > og matche så meget som muligt
- faktisk lige indtil sidste tag før </body...>.

En anden mulighed er fx:
$html =
preg_replace('#^(.*)<body(\s[^>]*)?>(.*)</body\s*>.*$#si','$3',$html);

--
- Peter Brodersen

Thomas Lindgaard (08-03-2005)
Kommentar
Fra : Thomas Lindgaard


Dato : 08-03-05 14:32

On Sat, 05 Mar 2005 15:12:28 +0100, Peter Brodersen wrote:

> .*? er et lazy match

Ahh ja, naturligvis... jeg skal vist lige rette på hovedet...

<skrue> <skrue> <skrue>

--
Mvh.
/Thomas


Peter Anskjær (05-03-2005)
Kommentar
Fra : Peter Anskjær


Dato : 05-03-05 11:41

"Peter Brodersen" <usenet2005@ter.dk> skrev i en meddelelse
news:d0au3e$iks$1@news.klen.dk...
> On Sat, 5 Mar 2005 01:15:12 +0100, "Peter Anskjær"
> <peter@_fjern_dette_nskjaer.dk> wrote:
>
>>Men nu er min tanke om man ikke kan lave det med noget preg_replace hvor
>>replacement er "".
>
> $html =
> preg_replace('#^(.*)<body(\s+.*?)?>(.*)</body\s*>.*$#si','$3',$html);
>
> Så har du kun indholdet mellem <body> og </body> tilbage
>
Tak for hjælpen. Jeg er bestemt ikke med på alle delene af udtrykket, men
jeg forsøger lige at læse lidt mere om reg exp, måske vender jeg tilbage
efter lidt forklaring hvis det er ok.
Det virker i hvert tilfælde lige som det skal, så det må siges der var en
god grund til at bruge reg exp's.
Har kørt en trim på den bagefter for at slippe for linjeskiftene efter
<body> og før </body>, det kunne man jo sikkert også tage ud med reg-exp,
men trim er vel ok.

Mvh
Peter



Peter Anskjær (05-03-2005)
Kommentar
Fra : Peter Anskjær


Dato : 05-03-05 15:23

"Peter Brodersen" <usenet2005@ter.dk> skrev i en meddelelse
news:d0au3e$iks$1@news.klen.dk...
> On Sat, 5 Mar 2005 01:15:12 +0100, "Peter Anskjær"
> <peter@_fjern_dette_nskjaer.dk> wrote:
>
>>Men nu er min tanke om man ikke kan lave det med noget preg_replace hvor
>>replacement er "".
>
> $html =
> preg_replace('#^(.*)<body(\s+.*?)?>(.*)</body\s*>.*$#si','$3',$html);
>
> Så har du kun indholdet mellem <body> og </body> tilbage
>
Jeg tror nu jeg har forstået det meste, dog er jeg ikke helt sikker på
hvorfor det hele er onkranset af #, er det for at adskille udtrykket fra si?
Jeg antager dette (\s+.*?)? er for at undgå at andre tags såsom <bodynoget>
skal kunne fanges. Kunne man ikke bare bruge (.*?) eftersom body er eneste
tag der starter med body eller overser jeg noget?

Mvh
Peter



Peter Brodersen (05-03-2005)
Kommentar
Fra : Peter Brodersen


Dato : 05-03-05 15:47

On Sat, 5 Mar 2005 15:22:32 +0100, "Peter Anskjær"
<peter@_fjern_dette_nskjaer.dk> wrote:

>Jeg tror nu jeg har forstået det meste, dog er jeg ikke helt sikker på
>hvorfor det hele er onkranset af #, er det for at adskille udtrykket fra si?

Uanset om du har flag med eller ej, så skal udtrykket altid omkranses
af delimiters, når du bruger preg-funktionerne. Normalt bruger man /,
men jeg har brugt # i dette tilfælde (for ikke at behøve at escape
undervejs, fx <\/body> ). s og i er så regex-flag, der hhv. gør at
punktum også matcher newlines, og at søgningen ikke er case-sensitive.

>Jeg antager dette (\s+.*?)? er for at undgå at andre tags såsom <bodynoget>
>skal kunne fanges. Kunne man ikke bare bruge (.*?) eftersom body er eneste
>tag der starter med body eller overser jeg noget?

Jo, det kunne man sagtens. Jeg har måske bare overimplementeret lidt
:) I praksis vil <body(.*?)> sikkert virke perfekt.

--
- Peter Brodersen

Peter Anskjær (05-03-2005)
Kommentar
Fra : Peter Anskjær


Dato : 05-03-05 17:03

"Peter Brodersen" <usenet2005@ter.dk> skrev i en meddelelse
news:d0cgpr$3a7$2@news.klen.dk...
>
> Uanset om du har flag med eller ej, så skal udtrykket altid omkranses
> af delimiters, når du bruger preg-funktionerne. Normalt bruger man /,
> men jeg har brugt # i dette tilfælde (for ikke at behøve at escape
> undervejs, fx <\/body> ). s og i er så regex-flag, der hhv. gør at
> punktum også matcher newlines, og at søgningen ikke er case-sensitive.
>
Flagenes betydning havde jeg slået op, men jeg er ikke helt med på at escape
undervejs, i hvert tilfælde ikke med det eksempel du giver der (er med på at
specialtegn skal escapes, men ikke normal tekst såsom body).

>
> Jo, det kunne man sagtens. Jeg har måske bare overimplementeret lidt
> :) I praksis vil <body(.*?)> sikkert virke perfekt.
>
Better safe than sorry

Mvh
Peter



Peter Brodersen (05-03-2005)
Kommentar
Fra : Peter Brodersen


Dato : 05-03-05 17:23

On Sat, 5 Mar 2005 17:02:30 +0100, "Peter Anskjær"
<peter@_fjern_dette_nskjaer.dk> wrote:

>Flagenes betydning havde jeg slået op, men jeg er ikke helt med på at escape
>undervejs, i hvert tilfælde ikke med det eksempel du giver der (er med på at
>specialtegn skal escapes, men ikke normal tekst såsom body).

Ved #...# udgør #-tegnet en delimiter. Den adskiller det regulære
udtryk fra eventuelle flag. Man kan bruge stort set det tegn, man vil,
fx /.../ eller !...! , etc.

Det forudsætter dog, at det tegn, man bruger, ikke indgår i det
regulære udtryk. Hvis det gør det, så skal det escape's. Så følgende
to er gyldige udtryk:
#<body>(.*?)</body>#
/<body>(.*?)<\/body>/

Men ikke:
/<body>(.*?)</body>/

Her er der altså tre skråstreger, så det regulære udtryk vil blot være
"<body>(.*?)<" og så vil "body>/" blive betragtet som flag - hvilket
ikke er meningen.

Så det er udelukkende af læsevenligheden, at jeg bruger en anden
delimiter end /.../ - tænk fx på hvis man skal matche en simpel URL:
/http:\/\/(.*?)\/mappe\//
i forhold til:
_http://(.*?)/mappe/_

--
- Peter Brodersen

Peter Anskjær (05-03-2005)
Kommentar
Fra : Peter Anskjær


Dato : 05-03-05 18:39

"Peter Brodersen" <usenet2005@ter.dk> skrev i en meddelelse
news:d0cmd8$8cn$1@news.klen.dk...
> On Sat, 5 Mar 2005 17:02:30 +0100, "Peter Anskjær"
> <peter@_fjern_dette_nskjaer.dk> wrote:
>
>>Flagenes betydning havde jeg slået op, men jeg er ikke helt med på at
>>escape
>>undervejs, i hvert tilfælde ikke med det eksempel du giver der (er med på
>>at
>>specialtegn skal escapes, men ikke normal tekst såsom body).
>
> Ved #...# udgør #-tegnet en delimiter. Den adskiller det regulære
> udtryk fra eventuelle flag. Man kan bruge stort set det tegn, man vil,
> fx /.../ eller !...! , etc.
>
> Det forudsætter dog, at det tegn, man bruger, ikke indgår i det
> regulære udtryk. Hvis det gør det, så skal det escape's. Så følgende
> to er gyldige udtryk:
> #<body>(.*?)</body>#
> /<body>(.*?)<\/body>/
>
> Men ikke:
> /<body>(.*?)</body>/
>
> Her er der altså tre skråstreger, så det regulære udtryk vil blot være
> "<body>(.*?)<" og så vil "body>/" blive betragtet som flag - hvilket
> ikke er meningen.
>
> Så det er udelukkende af læsevenligheden, at jeg bruger en anden
> delimiter end /.../ - tænk fx på hvis man skal matche en simpel URL:
> /http:\/\/(.*?)\/mappe\//
> i forhold til:
> _http://(.*?)/mappe/_
>
Ahh, så er jeg med, af en eller anden grund havde jeg kigget på den første
body, altså <body og ikke </body, ved ikke hvorfor jeg ikke lige tænkte på
nr. 2, derfor blev jeg lidt forvirret.
Tak for hjælpen, jeg vil til at finde nogle flere steder at bruge reg exp's
da det godt nok er smart.

Mvh
Peter



Søg
Reklame
Statistik
Spørgsmål : 177501
Tips : 31968
Nyheder : 719565
Indlæg : 6408527
Brugere : 218887

Månedens bedste
Årets bedste
Sidste års bedste