Perl Regulärer Ausdruck: Jeden Treffer in einem String einzeln verarbeiten - wie?

Tuxman

Banned
Registriert
Feb. 2007
Beiträge
1.497
'hoi,

ich bringe mir gerade per "learning by doing" Perl bei (ist für uns PHP'ler ja erträglicher Lernaufwand). Aktuell habe ich ein kleines irssi-Skript, das auf bestimmte Eingaben reagiert, geschrieben, eine Art "Wikipedia-Verlinker". Dafür benutze ich einen regulären Ausdruck. Das funktioniert, leicht paraphrasiert, so:

1. Ein Benutzer im IRC schreibt zum Beispiel "[[Käse]]".
2. Mein Script wandelt das in einen Wikipedia-Link um und gibt den aus.

Das momentane Script:

Code:
use strict;
use Encode qw(encode decode);
use Irssi qw(signal_add);

sub linkify {
    my ($text) = @_;

    $text =~ s/ /_/gm;
    $text =~ s/\[\[|\]\]|\{\{|\}\}//gm;
    return $text;
}

sub wikilink {
    my ($server, $message, $nick, $address, $target) = @_;

    $_ = decode('utf-8',$message);  # recognize umlauts

    if (/\[\[(\w|\s|!|#|\/|\.|-|\(|\)|\\|{|}|_|^|°|,|`|\/|;|'|\:|\[\])*\]\]/i) {
        my $retval = "http://de.wikipedia.org/wiki/" . encode('latin1',linkify($&));
        $server->command("MSG $target $retval");
    }
    elsif (/\{\{(\w|\s|!|#|\/|\.|-|\(|\)|\\|{|}|_|^|°|,|\`|\/|;|'|\:|\[|\])*\}\}/i) {
        my $retval = "http://de.wikipedia.org/wiki/Vorlage:" . encode('latin1',linkify($&));
        $server->command("MSG $target $retval");
    }

    return 0;
}

signal_add("message public","wikilink");

(Das geht wahrscheinlich auch irgendwie einfacher, aber es erfüllt seinen Zweck bislang so weit ganz gut.)

Nun hätte ich gern die Möglichkeit, dass mehr als ein Link möglich ist, zum Beispiel in diesem Chatausschnitt:

<ich> ich gehe ins [[Büro]] und mache was mit [
PHP:
][/quote]

Mein aktuelles Skript sieht nur einen Wikipedialink vor, es würde also schreiben:

[quote]http://de.wikipedia.org/wiki/Büro_und_mache_was_mit_PHP[/quote]

Vermutlich müsste ich den regulären Ausdruck anpassen und irgendwo eine Schleife setzen. Nur wo und wie?
Zu Hülf'!
 
Ich keine zwar Dein Modul Irssi nicht, aber an sich sollte es so:
Code:
sub linkify {
 my $text = shift;
 $text =~ y/ /_/;
 $text =~ y/[]{}//d;
 $text
}
     
sub wikilink {
 # my ($server, $message, $nick, $address, $target) = @_;
 my $message = shift;
 my $msg = encode('utf-8', $message); # recognize umlauts
 
 if( $msg =~ / [\[\{]{2} [^\[\{]+ [\}\]]{2} /x) {
    my $retval = "http://de.wikipedia.org/wiki/" . encode('latin1', linkify($msg));
    print $retval;   # $server->command("MSG $target $retval");
 }
 return 0;
}
     
wikilink( encode('latin1', '[[Käse]]') ); # signal_add("message public", "wikilink");

gehen.
 
Das Modul "Irssi" ist das IRC-Modul von irssi, das für Befehle wie $server->command zuständig ist. :)

Dein Code macht die Umwandlung doch ebenfalls nur für einen einzigen Link...?
 
Ach so, Du meinst sowas:
Code:
sub linkify {
 my $text = shift;
 $text =~ y/ /_/,  $text
}

sub all_wikilinks {
 my $message = shift;
 my $wstart ='<a href="http://de.wikipedia.org/wiki/">';
 my $wend = '</a>';
 
 $message =~ s/
                [\[\{]{2}   # [[
                 \s*        # eventuell WS
               ( [^\[\{]+ ) # text als $1
                 \s*        # eventuell WS 
                [\}\]]{2}   # ]]
                /$wstart . linkify($1) . $wend/gsex;
 $message;
}

print
  all_wikilinks('<ich> ich gehe ins [[Bü ro]] und mache was mit [[PHP]]');
 
Ah, das sieht brauchbar aus. Danke, ich bastle mal damit. :)
 
Zurück
Oben