|  | 		    
					
        
         
          
         
	
          | |  | Regex, utilsigtet bivirkning med ekstra ba~ Fra : Jesper Brunholm
 | 
 Dato :  09-08-06 09:57
 | 
 |  | 
 
            Hejsa, jeg har en regex som hiver fodnoter med mere ud af databaselagret 
 indhold.
 Eks. på indhold:
 "... <p>Det er ikke rigtigt, at jeg har sendt "Politiken" noget Bidrag 
 til dets Drachmann-Nummer. Jeg har ikke engang været opfordret dertil, 
 og vilde heller ikke have gjort det, om det var sket. I vistnok 15 År 
 har jeg ikke set Drachmann, og i den Tid heller ikke skrifligt vekslet 
 Ord med ham.<slutnote><em>skriftligt vekslet Ord</em>: Det kendes kun 
 tre  <a 
 href="http://www.henrikpontoppidan.dk/text/kilder/breve/drachmann/index.html">breve fra HP</a> til Drachmann, det ældste er fra sommeren 1890, det næste fra 
 Berlin (22.12.1890), og det sidste er ikke 15, men 13 år gammelt 
 (29.12.1893). Men Pontoppidans formulering antyder at der tidligere har 
 været en også brevlig tættere kontakt mellem dem. Selv bevarede 
 Pontoppidan kun to breve fra Drachmann, det ene citerede han i <em>Arv 
 og Gæld???</em>, den andet ....</slutnote> Men jeg har jo i sin Tid 
 holdt meget af ham, og nu ved hans Fest..." [1]
 PHP-kode:
 function slutnote($notetekst){
   global $slutnoter, $noteT_B; #slutnoter er et array hvori noterne 
 opbevares. $noteT_B er et array hvor notenumre konverteres til bogstaver 
 (fordi det er slutnoter som skal kunne skelnes fra fodnoter)
   $pos=strtr(count($slutnoter), $noteT_B);
   $slutnoter[$pos] = $notetekst;
   $MyReturn = '<sup class="fodhenv"><a href="#fod'.$pos.'" 
 title="'.strip_tags($notetekst).'" id="note'.$pos.'">'.$pos.'</a></sup>';
   return $MyReturn;
 }// slutnote()
 function udtraekNoter($tekst,$type='slutnote'){ # der kan både være 
 <fodnote> og <slutnote>'r
    $notepos = strpos($tekst, '<'.$type.'>');
    if(FALSE !== $notepos){
         $pattern='/<'.$type.'>(.*)<\/'.$type.'>/Ue';
      $tekst = preg_replace($pattern, "$type('\\1')", $tekst);
    }
    return $tekst;
 }// udtraekNoter()
 - og endelig en funktion som printer fod- og slutnoterne ud nederst på 
 siden.
 Det virker fint så længe der ikke er links i noteteksten. Det virker 
 også fint med fodnoter sat direkte i php-filer med <?php 
 fodnote('fodnotetekst her'); ?> med links i, så det er regex'en som 
 bugger links op og sætter ekstra anførselstegn-kode , de bliver fx. til:
 "tre  <a 
 href=\"http://www.henrikpontoppidan.dk/text/kilder/breve/drachmann/index.html\">breve fra HP</a> til Drachman" - hvor altså \ er i overskud. Det kan ses i 
 funktion på 
 <http://www.henrikpontoppidan.dk/text/kilder/breve/borchsenius/1906_10_16.html#foda> Kan nogen rette min regex, og gerne med forklaring?
 Jeg er ikke ret hård til regex, og synes oprigtigt talt det er svært at 
 finde rundt i hvad der gør hvad. Det vil også sige at en god tutorial 
 til PHP (preg-)regex funktioner modtages med tak (og ja, jeg har læst 
 php-manualen igennem et par gange på det område    ).
 Mvh
 Jesper Brunholm
 [note 1: brevet er fra Henrik Pontoppidan til Otto Borchsenius og kan 
 ses på 
 <http://www.henrikpontoppidan.dk/text/kilder/breve/borchsenius/1906_10_16.html> hvis nogen er interesserede i resten af indholdet].
            
             |  |  | 
  Peter Brodersen (09-08-2006) 
 
	
          | |  | Kommentar Fra : Peter Brodersen
 | 
 Dato :  09-08-06 15:17
 | 
 |  | 
 
            On Wed, 09 Aug 2006 10:56:55 +0200, Jesper Brunholm
 <nospam@brunholm-scharff.dk> wrote:
 >Kan nogen rette min regex, og gerne med forklaring?
 Når du bruger e-modfieren til at afvikle PHP-kode med den matchede
 tekst - og det gør du her:
         $pattern='/<'.$type.'>(.*)<\/'.$type.'>/Ue';
      $tekst = preg_replace($pattern, "$type('\\1')", $tekst);
 ... så bliver der afviklet addslashes til de matchede udtryk. Hvis du
 holder dig til kun at bruge gåseøjne, kan du måske klare dig med at
 rette nederste linje til:
      $tekst = preg_replace($pattern, '$type("\\1")', $tekst);
 ... idet det så ikke er noget problem at matchede gåseøjne får en gang
 backslashes foran sig.
 Generelt er PHPs PCRE-funktioner temmeligt klodsede i den retning,
 sådan som de har valgt at implementere det.
 Man kan dog undgå addslashes()-helvedet ved at bruge
 preg_replace_callback() (med lidt omskrevet kode), hvilket i mange
 tilfælde er at foretrække, hvis man risikerer at matche både ' og ".
 Det er kun relevant, når man bruger e-flaget til sit regulære udtryk.
 Det kræver dog en del mere kode, hvilket er irriterende i tilfælde,
 hvor det ellers havde været i det regulæres udtryks ånd at referere
 til de enkelte matchede dele i ét replace-udtryk.
 preg_replace: http://php.net/preg-replace-callback Et eksempel på den måske lidt uventede opførsel for preg_replace:
 <?php
 $string = <<<EOD
 Foo ' Bar " Baz
 EOD;
 print preg_replace('/.*/e','"$0"',$string)."\n";
 print preg_replace('/.*/e',"'$0'",$string)."\n";
 ?>
 Dette outputter følgende:
 Foo \' Bar " Baz
 Foo ' Bar \" Baz
 Måske ikke hvad man havde forventet.
 -- 
 - Peter Brodersen
   Ugens^WMånedens^WSommerens værktøj - Find vej: www.findvej.dk   Nu med valgfri tekst: www.findvej.dk/Nybrogade2,1203?text=Kulturministeriet |  |  | 
  Bertel Lund Hansen (09-08-2006) 
 
	
          | |  | Kommentar Fra : Bertel Lund Hansen
 | 
 Dato :  09-08-06 15:36
 | 
 |  | 
 
            Peter Brodersen skrev:
 > Generelt er PHPs PCRE-funktioner temmeligt klodsede i den retning,
 > sådan som de har valgt at implementere det.
 Jeg har kun sat mig meget nødtørftigt ind i regulære udtryk. Til
 brug i en funktion har jeg lavet følgende:
 function is_harmless   ($newentry plus flere parametre) {
    $harmless=array('','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','');
    $harmful=array('@', '%', "\\", '/', '<', '>', '(', ')', ';', '!', ':', '"', "'", 'script');
    $lowcaseentry=strtolower($newentry);
    $newlowentry=str_replace($harmful,$harmless,$lowcaseentry);
    [en masse specialkode]
    return $newlowentry==$lowcaseentry;
 }
 Det synes jeger nemt at have med at gøre, men det er måske bare
 min dovenskab?
 -- 
 Bertel
http://bertel.lundhansen.dk/      http://fiduso.dk/ |  |  | 
   Peter Brodersen (09-08-2006) 
 
	
          | |  | Kommentar Fra : Peter Brodersen
 | 
 Dato :  09-08-06 17:00
 | 
 |  | 
 
            On Wed, 9 Aug 2006 16:35:56 +0200, Bertel Lund Hansen
 <nospamfilius@lundhansen.dk> wrote:
 >Jeg har kun sat mig meget nødtørftigt ind i regulære udtryk. Til
 >brug i en funktion har jeg lavet følgende:
 >
 >function is_harmless   ($newentry plus flere parametre) {
 >   $harmless=array('','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','');
 >   $harmful=array('@', '%', "\\", '/', '<', '>', '(', ')', ';', '!', ':', '"', "'", 'script');
 >   $lowcaseentry=strtolower($newentry);
 >   $newlowentry=str_replace($harmful,$harmless,$lowcaseentry);
 For en god ordens skyld kan du erstatte $harmless med ''. Du behøver
 ikke at have et array for hver entry, hvis de alligevel skal erstattes
 med det samme:
http://php.net/str-replace "If search  is an array and replace is a string, then this replacement
 string is used for every value of search."
 Din søgning efter "script" synes jeg er lidt pudsig. Hvorfor ikke
 eval, når du er i gang (hvilket i andre tilfælde har gået ud over
 folk, som har snakket om "medieval"    )
 >Det synes jeger nemt at have med at gøre, men det er måske bare
 >min dovenskab?
 Det er også brugbart nok i dit tilfælde. Det er også let nok at lave
 med et regulært udtryk, hvor man ikke kommer ud i at skulle lave andet
 end simple søg&erstatninger.
 Det komplekse opstår, når man vil tage dele af det matchede - uden at
 kende det på forhånd - og så afvikle noget PHP-kode for denne
 specielle del.
 At finde alle tekststykker, der ligner telefonnumre, og markere dem
 med fed, kan også gøres uden videre meget simpelt med regulære udtryk,
 uden at skulle evaulere noget.
 I det aktuelle tilfælde skal den matchede data (som man vel at mærke
 ikke kender på forhånd) behandles, før den lægges tilbage igen. Her
 kan eval/callback-funktionerne så være praktiske nok.
 -- 
 - Peter Brodersen
   Ugens^WMånedens^WSommerens værktøj - Find vej: www.findvej.dk   Nu med valgfri tekst: www.findvej.dk/Nybrogade2,1203?text=Kulturministeriet |  |  | 
  Jesper Brunholm (09-08-2006) 
 
	
          | |  | Kommentar Fra : Jesper Brunholm
 | 
 Dato :  09-08-06 20:16
 | 
 |  | Peter Brodersen skrev:
 > Når du bruger e-modfieren til at afvikle PHP-kode med den matchede
 > tekst - og det gør du her:
 >
 >         $pattern='/<'.$type.'>(.*)<\/'.$type.'>/Ue';
 >      $tekst = preg_replace($pattern, "$type('\\1')", $tekst);
 >
 > .. så bliver der afviklet addslashes til de matchede udtryk. Hvis du
 > holder dig til kun at bruge gåseøjne, kan du måske klare dig med at
 > rette nederste linje til:
 >
 >      $tekst = preg_replace($pattern, '$type("\\1")', $tekst);
 
 Det virkede helt efter hensigten, mange tak. Jeg troede ikke at den
 ville parse $type når det stod i enkelte anførselstegn, men der gælder
 åbenbart andre regler her.
 
 mvh
 
 Jesper Brunholm
 
 
 |  |  | 
 |  |