Avatar billede dennism Nybegynder
02. september 2010 - 20:54 Der er 8 kommentarer og
1 løsning

Fjern HTML-tag fra string

Jeg har forsøgt at lave en funktion i PHP, som kan fjerne den første forekomst af et HTML-tag fra en string samt dets korrekte end-tag'et i forhold til DOM træet.

Lad os f.eks. tage dette eksempel:
[code]<p>
    <div>
        <p>test</p>
    </div>
</p>
<div>test</div>[/code]

Det skal efter det er kørt igennem funktionen, med fjernelse af første p-tag, blive til:
[code]    <div>
        <p>test</p>
    </div>
<div>test</div>[/code]

Bemærk, at den ikke koncentrerer sig om indent.

Her er den funktion jeg har lavet:
[code]function remove_first_tag($var, $tag) {
  $tagStart = '<'.$tag.'>';
  $tagEnd = '</'.$tag.'>';
 
  $pos = strpos($var,$tagStart);
  if(!($pos === FALSE)) {
    $posStartTag = $pos;
   
    $level = 0;
   
    for ($n=0;!isset($posEndTag) && $n-strlen($tagEnd)<strlen($var);$n++) {
      $tmp_var = substr($var, $n);
       
      if (substr($tmp_var, 0, strlen($tagStart))==$tagStart)
        $level++;
      if (substr($tmp_var, 0, strlen($tagEnd))==$tagEnd) {
        $level--;
        if ($level==0) {
          $posEndTag=$n;
        }
      }
    }
  }
 
  //removing start tag
  if (isset($posStartTag))
    $var = substr($var, 0, $posStartTag ).substr($var, $posStartTag+strlen($tagStart));
  //removing end tag
  if (isset($posEndTag))
    $var = substr($var, 0, $posEndTag-strlen($tagStart)).substr($var, $posEndTag-strlen($tagStart)+strlen($tagEnd));
 
  return $var;
}[/code]

Funktionen kan køres på denne måde:
[code]$var = remove_first_tag($string,'p');[/code]

Mit spørgsmål går blot på, om der findes en bedre måde at løse denne problemstilling på?
Avatar billede dennism Nybegynder
02. september 2010 - 20:58 #1
Øv, det gik helt galt med dette indlæg.

I kan læse en mere læsevenlig version her:
http://uploads.dennismadsen.com/spm917922.txt
Avatar billede Slettet bruger
02. september 2010 - 21:28 #2
Det er pænt langhåret/ambitiøst...
- ikke mindst, hvis du kan risikere at HTML'en ikke er 100% valid ?
(og de fleste tags har jo attributter tilknyttet som ikke gør det lettere)

Umiddelbart ville jeg anbefale at "køre det igennem" noget XML-validering.
- og så tage den dérfra, med XML-tool-classes (ikke et rigtigt ord)
Avatar billede Slettet bruger
02. september 2010 - 21:32 #3
For ikke at tale om sider med javascript, som indeholder HTML i strenge...
Avatar billede intenz Novice
03. september 2010 - 11:18 #4
Af ren nysgerrighed, hvorfor har du behov for det?
Avatar billede dennism Nybegynder
03. september 2010 - 11:26 #5
Jeg sidder og arbejder i WordPress. Jeg har indsat et tag i et indlæg, for at vise en kontaktformular (Contact Form 7 - wpcf7). WordPress sætter først <p> og <br> tags på indlæg lige inden de udskrives i frontend. Desværre betyder det, at jeg i en bestemt situation ender med:
<p><div class="wpcf7">...</div></p>

Og det er ikke valid XHTML. Så er nødt til at fjerne det første <p>, hvis der findes en div med klassen wpcf7.

Håber det giver lidt mening. Ved godt det virker ret uanvendeligt, men jeg er meget bevidst omkring validaring.
Avatar billede intenz Novice
03. september 2010 - 14:28 #6
Hvis det kun er det du skal bruge din funktion til, så brug bare den du selv har lavet (hvis den virker). Dit oprindelige spørgsmål var om der "findes en bedre måde at løse denne problemstilling på". Der findes nok mange måder at løse det på, men ingen nem måde, da det er 'problem' der bør løses inden det opstår (der bør aldrig sættes <p></p> på hvis det ikke skal bruges). Det vil være den 'rigtige' måde at løse det på, det du forsøger er symptom-behandling.

Nu hvor det er sat på, og det kun skal bruges i en så præcis sammenhæng, så er det du har lavet fint. Eller en hvilken som helst anden måde. Bare ikke forvent, at det _altid_ vil fungere, da der som #2 skriver kan være mange variationer af tags.
Avatar billede intenz Novice
03. september 2010 - 14:57 #7
Hvis du vil ofre fleksibiliteten, og dine tags altid står først/sidst i din streng (hvilket måske er usandsynligt), er den nemmeste måde bare at substr dem ud:
http://php.net/manual/en/function.substr.php

function removeFirstLastTag($str, $tag) {
  $firstTag = '<'+$tag+'>';
  $lastTag = '</'+$tag+'>';

  return substr($str, strlen($firstTag), (-1)*strlen($lastTag));
}

Hvis du kun har behov for at gøre det med <p></p> og evt. <br>, så lad være med at lave en generisk funktion der potentielt kan gøre det med alle typer tags i alle typer stregne. Det er ingen grund til at overkomplicere det hvis du aldrig får brug for det.
Avatar billede dennism Nybegynder
17. september 2010 - 00:21 #8
Vil I begge smide et svar - så kan I dele point.
Avatar billede intenz Novice
17. september 2010 - 09:04 #9
Kommer et her
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester