Markus Trusk: Regulärer Ausdruck will nicht funktionieren?

Hi,
Seit Stunden versuche ich jetzt dahinter zu kommen, warum folgender Ausdruck nicht funktioniert.
Ich habe in einem Text eine Passage, die so aussieht:

[text][Textfarbe=hellblau,Stil=hochgestellt,Size=+3]TEST[/text]

...schreibe ich auch einen Link, der keiner ist in den Text, also www.testirgendwas.com, wird auch dieser erfolgreich zu einem Link kodiert.

..und eine weitere Passage, die so aussieht:
[link][name=tester.com]http://tester.com[/link]

In folgender Subroutine wird ebenfalls das [link]...[/link] Feld erfolgreich zu einem Link kodiert, aber der oberste Text funktioniert nicht, und ich verstehe nicht warum. Der Text wird einfach nicht kodiert. Ich habe bereits zur Probe ein exit; innerhalb der while Schleife platziert, und das Script brauch ab, was bedeutet (falls ich mit meiner Logik noch nicht ganz am Ende bin), dass die while Schleife den Text erkennt, aber warum wandelt sie den Text nicht um (weiter unten in der sub soll das geschen). Das Kuriose ist aber, dass die selbe Sub in einem älteren Script funktioniert, aber in diesem Script nicht, obwohl ich keine Unterschied feststellen kann. Es wird der "rohe" $text entgegengenommen, und der kodierte $text wieder zurückgegeben.

Ich kann leider kein Beispiel zeigen, da das Forum-Script noch lange nicht fertig ist.

sub encodetext   {
my $text = shift;
   while ($text =~ /[text][Textfarbe=(.*?),Stil=(.*?),Size=(.*?)](.+?)[/text]/sgi)    {
   my($stil,$farbe,$groesse,$text) = ('') x 4;
   ($farbe,$stil,$groesse,$text) = ($1,$2,$3,$4);

$stil = 'text-decoration:normal;' if ($stil eq '' || $stil eq 'keine');
          $stil = 'text-decoration:underline;' if $stil eq 'unterstrichen';
          $stil = 'font-weight:bold;' if $stil eq 'fett';
          $stil = 'font-style:italic;' if $stil eq 'kursiv';
          $stil = 'text-decoration:line-through;' if $stil eq 'durchgestrichen';
          $stil = 'vertical-align:super;' if $stil eq 'hochgestellt';

$farbe = 'color:#DFDFDF;' if ($farbe eq '' || $farbe eq 'keine');
          $farbe = 'color:#FF80C0;' if $farbe eq 'rosa';
          $farbe = 'color:#FF0000;' if $farbe eq 'rot';
          $farbe = 'color:#FF8000;' if $farbe eq 'orange';
          $farbe = 'color:#FFFF00;' if $farbe eq 'gelb';
          $farbe = 'color:#B0B0FF;' if $farbe eq 'hellblau';
          $farbe = 'color:#00009D;' if $farbe eq 'dunkelblau';
          $farbe = 'color:#00FF00;' if ($farbe eq 'hellgruen' || $farbe eq 'hellgrün');
          $farbe = 'color:#005900;' if ($farbe eq 'dunkelgruen' || $farbe eq 'dunkelgrün');
          $farbe = 'color:#00FFFF;' if ($farbe eq 'tuerkis' || $farbe eq 'türkis');

$groesse = 'font-size:11px' if ($groesse eq '' || $groesse eq 'keine');
          $groesse = 'font-size:8px' if $groesse eq '-2';
          $groesse = 'font-size:9px' if $groesse eq '-1';
          $groesse = 'font-size:12px' if $groesse eq '+1';
          $groesse = 'font-size:14px' if $groesse eq '+2';
          $groesse = 'font-size:17px' if $groesse eq '+3';
          $groesse = 'font-size:19px' if $groesse eq '+4';
          $groesse = 'font-size:21px' if $groesse eq '+5';
          $groesse = 'font-size:24px' if $groesse eq '+6';
          $groesse = 'font-size:28px' if $groesse eq '+7';

$text =~ s/[text][Textfarbe=.*?,Stil=.*?,Size=.*?].+?[/text]/<span style="$farbe $stil $groesse">$text</span>/si;
   }
   $text =~ s/(\s|^)http://([^<>\s]{6,})/$1<a href="http://$1">$2</a>/isg;
   $text =~ s/(\s|^)www.([^<>\s]{6,})/$1<a href="http://www.$2">http://www.$2</a>/isg;
   $text =~ s/\n/<br />/g;
   $text =~ s/(\s\s+)/(' ' x (length($1)-1)) . ' '/eg;
   $text =~ s/[s(\d+?)]/<img src="pics/smiley$1.gif" alt="" />/g;
   $text =~ s/[link][name=(.+?)](.+?)[/link]/<a href="$2">$1</a>/g;

return ($text);
}

Markus Trusk.

  1. hallo markus,

    $text =~ s/(\s|^)http://([^<>\s]{6,})/$1<a href="http://$1">$2</a>/isg;
       $text =~ s/(\s|^)www.([^<>\s]{6,})/$1<a href="http://www.$2">http://www.$2</a>/isg;

    versuche mal diese zeilen in eine zu schreiben,
    also ein link ist nur ein link wenn er mit 'http://www.' begint
    dann wird 'www.' nicht gefunden.

    gruß
    qp

    1. Hi,

      versuche mal diese zeilen in eine zu schreiben,
      also ein link ist nur ein link wenn er mit 'http://www.' begint
      dann wird 'www.' nicht gefunden.

      Es gibt immer wieder Leute, die nur www.link.com in den Text tippen, und auch so ein "Link" soll in einen klickbaren Link verwandelt werden, aber das ist eigentlich nicht mein Problem, wie oben schon genannt.

      Markus Trusk.

  2. Hallo Markus Trusk,

    [...]

    Ich kann leider kein Beispiel zeigen, da das Forum-Script noch lange nicht fertig ist.

    Du könntest aber ein Beispielskript online stellen, das nur diese Funktion zum Testen anbietet.

    sub encodetext   {
    my $text = shift;

    ^....... hier speicherst Du den zu kodierenden Text in $text

    while ($text =~ /[text][Textfarbe=(.*?),Stil=(.*?),Size=(.*?)](.+?)[/text]/sgi)    {
       my($stil,$farbe,$groesse,$text) = ('') x 4;

    ^....... hier speicherst Du den  Elementinhalt in $text

    ($farbe,$stil,$groesse,$text) = ($1,$2,$3,$4);

    $stil = 'text-decoration:normal;' if ($stil eq '' || $stil eq 'keine');
              $farbe = 'color:#DFDFDF;' if ($farbe eq '' ||
              $groesse = 'font-size:11px' if ($groesse eq '' || $groesse eq 'keine');

    Ich würde an Deiner Stelle ein Hash mit den entsprechenden Werten in einer Konfigurationsdatei ablegen:

    %config = (
        'stil' => {
            'unterstrichen' => 'text-decoration:underline;',
        },
        'textfarbe' => {
            'rosa' => 'color:#FF80C0;',
        },
        'size' => {
            '-2' => 'font-size:8px',
        },
    ); # Du musst die übrigen Werte natürlich noch ergänzen. :)

    $text =~ s/[text][Textfarbe=.*?,Stil=.*?,Size=.*?].+?[/text]/<span style="$farbe $stil $groesse">$text</span>/si;
       }

    Und hier möchtest Du Treffer in der Variablen $text (außerhalb der Schleife definiert) mit Werten der Variablen $text (innerhalb der Schleife definiert) ersetzen. Dreimal aber darfst Du raten, was in $text steht. ;)

    BTW: Bei Verwendung des Konfigurationshash wie oben vorgeschlagen, kannst Du Dir die Ersetzung vereinfachen, von einer Reihenfolge der Attributwerte unabhängig machen und die while-Schleife sparen:

    $text =~ s/[text]
               [([^=]+?)=(.*?),
                 ([^=]+?)=(.*?),
                 ([^=]+?)=(.*?)
               ]
               (.+?)
               [/text]
              /'<span style="'.
               $config{lc($1)}->{$2}.
               $config{lc($3)}->{$4}.
               $config{lc($5)}->{$6}.
               '">'.$7.'</span>'
              /sexig;

    Noch besser wäre imho, erst die tags mit den Pseudoattributen zu schreiben, und diese anschließend in einem zweiten Schritt global zu ersetzen. Dann müssten natürlich die Pseudoattribute überall die gleiche Bedeutung haben, bzw. eindeutig sein. Dafür wäre aber die Reihenfolge und das Vorhandensein bestimmter Attribute beliebig.

    [...]

    return ($text);
    }

    Das Kuriose ist aber, dass die selbe Sub in einem älteren Script funktioniert, aber in diesem Script nicht, obwohl ich keine Unterschied feststellen kann.

    Es gibt sicherlich einen Unterschied. Vielleicht hattest Du die Variablen anders benannt.

    Gruß Alex

    --
    >> Dass in eine if Schleife zu packen schafft mein 10 jähriges Patenkind. [...]
    > Mhhh, wenn man if in Schleifen packt, muss man sich auch nicht wundern, wenn die Patenkinder verwöhnte Luder werden. [...]
    [TomIRL und Tom in ?t=64084&m=364291]
    ss:) zu:} ls:} fo:| de:[ va:| ch:| sh:( n4:& rl:° br:& js:| ie:| fl:| mo:}
    1. Hallo,

      sub encodetext   {
      my $text = shift;
             ^....... hier speicherst Du den zu kodierenden Text in $text

      while ($text =~ /[text][Textfarbe=(.*?),Stil=(.*?),Size=(.*?)](.+?)[/text]/sgi)    {
         my($stil,$farbe,$groesse,$text) = ('') x 4;
                                     ^....... hier speicherst Du den  Elementinhalt in $text

      Vielen dank. Ehrlich gesagt wäre ich hier nicht draufgekommen. In meinem anderen Script hat es deswegen funktioniert, weil der ganze Text in $changedtext gespeichert war, aber da in diesem Fall mein $changedtext, $text hieß, waren die beiden natürlich nicht mehr zu unterscheiden :)

      Markus Trusk.