Schrift
[thread]11637[/thread]

Tags finden

Leser: 1


<< |< 1 2 3 >| >> 22 Einträge, 3 Seiten
Froschpopo
 2008-04-13 18:34
#108312 #108312
User since
2003-08-15
2653 Artikel
BenutzerIn
[default_avatar]
Ich habe einen Text:

Code: (dl )
$text = "Dies ist [fett]ein fetter Text[/fett].";


Jetzt will ich einen regex konstruieren, der den fett-Tag zu HTML übersetzt und zwar so, dass man hinterher nur noch einen Hash brauch, nach dem Muster:
Code: (dl )
1
2
3
4
5
my %tags = (
fett => '<strong>%s</strong>',
kursiv => '<span style="font-style:italic">%s</span>
...
);


Ich dachte erst, dass man das irgendwie so machen könnte (ist nur ein Beispiel)
Code: (dl )
$text =~ s/\[([a-zA-Z]+)\](.*)\[\/$1\]/replace(...)/gex;


Das Beispiel soll zeigen, was ich ungefähr vorhabe. Natürlich kann ich $1 nur nach dem / verwenden. Aber ich fand, dass man mein Vorhaben damit gut veranschaulichen kann.
Habt ihr irgendeine Idee, wie man hier beginnen könnte?
topeg
 2008-04-13 19:08
#108314 #108314
User since
2006-07-10
2611 Artikel
BenutzerIn

user image
suchst du sowas?
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#!/usr/bin/perl

use strict;
use warnings;

my $text = "Dies ist [fett]ein fetter Text[/fett].";

my %tags = (
     fett    => '<strong>%s</strong>',
     kursiv => '<span style="font-style:italic">%s</span>'
);

# entweder so:
my $t=$text;
for my $key (keys(%tags))
{
 $t=~s|\[$key\](.+?)\[/$key\]|sprintf($tags{$key},$1)|egs;
}
print "$t\n";

#oder so:
$t=$text;
$t=~s|\[([^\[\]\W]+)\](.+?)\[/\1]|replace($1,$2)|egs;
print "$t\n";

sub replace
{ return sprintf($tags{shift(@_)},shift(@_)) }
Froschpopo
 2008-04-13 20:43
#108317 #108317
User since
2003-08-15
2653 Artikel
BenutzerIn
[default_avatar]
Wow, das sieht ziemlich cool aus!
Aber ich bin gerade am überlegen, wie man das noch erweitern könnte, dass auch Tags wie
Code: (dl )
[color=#404040]text[/color]

möglich sind.
topeg
 2008-04-13 22:55
#108320 #108320
User since
2006-07-10
2611 Artikel
BenutzerIn

user image
Eine Möglichkeit:
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#!/usr/bin/perl

use strict;
use warnings;

my $text = "Dies ist [fett]ein fetter Text[/fett]. [kursiv]Dieser ist Kursiv.[/kursiv] und hier haben wir die Farbe [color=#FF0000]rot[/color]";

my %tags = (
     fett    => '<strong>%s</strong>',
     kursiv => '<span style="font-style:italic">%s</span>',
     color => '<div style="color:%s;">%s</div>',
);

my $t=$text;
$t=~s|\[([^\[\]\W]+)\](.+?)\[/\1]|replace($1,$2)|egs;
$t=~s|\[([^\[\]\W]+)=([^\[\]]+)\](.+?)\[/\1]|replace_opt($1,$2,$3)|egs;
print "$t\n";

sub replace
{ return sprintf($tags{shift(@_)},shift(@_)) }

sub replace_opt
{ return sprintf($tags{shift(@_)},shift(@_),shift(@_)) }
Gast Gast
 2008-04-13 23:12
#108323 #108323
Huch frosch, willst du den BBCode-Parser jetzt selbst schreiben?
Froschpopo
 2008-04-14 01:12
#108330 #108330
User since
2003-08-15
2653 Artikel
BenutzerIn
[default_avatar]
jein.
Ich möchte eigene Tags verwenden.
Ich finde außerdem, dass diese BBCode-Module bei CPAN viel zu groß sind für die paar Funktionen die ich nur benötige.
Man muss ja nicht unnötig viel Laden was man garnicht braucht.
Wie topeq hier beweist, kann man das auch mit deutlich weniger Code realisieren.
Und zum Thema "das Rad neu erfinden": Bei der Kleinigkeit gleich ein Modul zu laden (das noch viel mehr bietet was ich aber nicht brauche) ist ja auch nicht besonders sinnvoll. Ich finde außerdem, dass so ein kleiner regex nicht mit einem "Rad" zu vergleichen ist ;)
renee
 2008-04-14 12:15
#108341 #108341
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Es ist bloß nicht immer ganz so einfach, weil man "vorrangige" Tags hat und "nachrangige". Innerhalb von [code]-Tags sollen natürlich keine anderen Tags ersetzt werden. Und so kann es noch mehr Regeln geben...
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
Froschpopo
 2008-04-14 12:25
#108343 #108343
User since
2003-08-15
2653 Artikel
BenutzerIn
[default_avatar]
Klar, man muss die Einhaltung der Regeln auch prüfen.
Aber ich habe den Syntax-Parser in ein extra Modul gepackt, weil der nicht so oft ausgeführt wird, will ich den auch nicht permanent im Arbeitsspeicher haben.
Es muss ja z.B. auch sichergestellt werden, dass in [list] wenigstens ein [*] vorkommt und [*] nur innerhalb von [list] vorkommen darf usw.
Aber ich will nicht alles in ein Modul packen wo ich es nicht brauche, erst recht nicht permanent in den Arbeitsspeicher, wenn es nur 5-10 mal am Tag ausgeführt wird. Das wäre ja quatsch.
Obiger Code hingegen wird schon über die startup.pl in den Apacheprozess eingebunden und muss schnell verfügbar sein. Deshalb auch dieser Geiz :) Ich habe halt nur 2 GB Ram.
Froschpopo
 2008-04-14 14:00
#108348 #108348
User since
2003-08-15
2653 Artikel
BenutzerIn
[default_avatar]
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
13: # entweder so:
14: my $t=$text;
15: for my $key (keys(%tags))
16: {
17: $t=~s|\[$key\](.+?)\[/$key\]|sprintf($tags{$key},$1)|egs;
18: }
19: print "$t\n";
20:
21: #oder so:
22: $t=$text;
23: $t=~s|\[([^\[\]\W]+)\](.+?)\[/\1]|replace($1,$2)|egs;
24: print "$t\n";
25:
26: sub replace
27: { return sprintf($tags{shift(@_)},shift(@_)) }


Welcher der beiden regexe ist eigentlich performanter bzw. empfehlenswerter?
Der zweite zeigt ja leider keine nicht-existierenden Tags an (z.b. [test] ).
Optisch gefällt mir der zweite deutlich besser, aber irgendwie vermute ich, dass der erste schneller ist. Kann das jemand bestätigen?
nepos
 2008-04-14 14:27
#108350 #108350
User since
2005-08-17
1420 Artikel
BenutzerIn
[Homepage] [default_avatar]
Wie waers, wenn du einfach selber mit Hilfe von CPAN:Benchmark einen kleinen Test machst :)
<< |< 1 2 3 >| >> 22 Einträge, 3 Seiten



View all threads created 2008-04-13 18:34.