[Dresden-pm] Reguläre Ausdrücke - Suchen und Ersetzen von Worten

Torsten Knorr create-soft at tiscali.de
Sa Aug 23 05:15:06 PDT 2008


=head
Thomas Rittsche Tue, 12 Aug 2008 10:04:11 +0200

>Hallo an alle,
>ich habe mal wieder ein Problem, bei dem ich Überhaupt keine Idee
>habe, wie man da rangehen könnte.
=cut
 use strict;
 use re 'eval';
# Ein Regexobjekt erstellen mache das gerne vorweg und nicht erst in einer Schleife
 my @kw	= ('affe', 'hund', 'affe klettert', 'hund rennt');
 my $str	= join('|', map { quotemeta($_) } @kw);
# wenn klaffen oder Menschenaffe nicht gefunden werden soll dann "\b" einfügen
# my $rx	= qr/\b($str)\b/i;
# wenn wirklich alles gefunden werden soll was die Schlüsselwörter enthält
 my $rx = qr/($str)/i;
 my $text = ' 
Ein Affe klettert, weil er ein Affe ist. Ein Hund rennt, weil er ein Hund ist.
Der Menschenaffe stirbt aus.
Der Menschenaffe klettert nicht so gut.
Auf die Bäume Ihr Affen.
Heute ist eine Affenhitze.
Die Meinungen klaffen auseinander.
';
 my (@m, $new);
 my $pos	= 0;
#-------------------------------------------------
=head
 Version: Aristoteles leicht optimiert produziert aber ungültiges HTML
 $text =~ m{$rx(?{
 	push(@m, [$-[0],  "<a href=\"$1.html\">"]);
 	push(@m, [$+[0], '</a>']);
 	})(?!)}xi;
 for(sort { $a->[0] <=> $b->[0] } @m)
 	{
 	$new	.= substr($text, $pos, $_->[0] - $pos) . $_->[1];
 	$pos	= $_->[0];
 	}
 $new		.= substr($text, $pos);
=cut
#-------------------------------------------------
# Version: Torsten wohlgeformtes HTML
# Alle Treffer einsammeln und in anonyme Arrays speichern
# 1. Element Treffer Anfang
# 2. Element Treffer Ende
# 3. Element Trefferinhalt
# anonyme Arrays in @m speichern
# (?{Code}) Code wird ausgeführt
 $text	=~ m{$rx(?{push(@m, [$-[0], $+[0], $1]);})(?!)};
# indirekte Sortierung der anonymen Arrays nach Treffer Anfang
# mit der niedrigsten Position beginnen
 for(sort { $a->[0] <=> $b->[0] } @m)
 	{
#ist neue Position im String größer gleich letzter Position
 	if($_->[0] >= $pos)
 		{
# Erst den String bis zum Trefferanfang hinzufügen dann
# einen Ankertag mit Start- und Endtag hinzufügen.
 $new .= substr($text, $pos, $_->[0] - $pos) . "<a href=\"$_->[2].html\">$_->[2]</a>";
 		}
 	else
 		{
# Erst Starttag hinzufügen dann
# bei sich Überschneidenten Teffern nur den Rest des Textes hinzufügen.
# Abschließend den Endtag nicht vergessen.
 $new .= "<a href=\"$_->[2].html\">" . substr($text,  $pos, $_->[1] - $pos) . '</a>';
 		}
# Position auf Ende des letzten Treffers setzten.
 	$pos	= $_->[1];
 	}
# Den Rest hinter den letzten Treffer hinzufügen.
 $new .= substr($text, $pos);
# Testen
 open(H, ">test.html") or die("error: $!\n");
 print(H $new);
 close(H);
 print($new);
# Zum Schluß:
# Bugs suchen und bei Autor beschweren :-)
#-------------------------------------------------
# T.


Mehr Informationen über die Mailingliste Dresden-pm