Frage zu RegEx
Johnny B.
- perl
0 Beat0 asdfasdf551 CPAN
Hallo geehrtes Forum,
ich habe zwei Strings:
$alle = '1 2 3 5 6 7 8 9 10 11 12';
$gesehen = '6 11 1';
Jetzt möchte ich $gesehen von $alle 'abziehen', d.h. alle Vorkommen von Zahlen aus $gesehen in $alle löschen, also:
$ergebnis = '2 3 5 7 8 9 10 12';
Bisherige Lösung: ich splitte die beiden Strings zu Arrays, erstelle eine lookup-Tabelle als Hash, prüfe jedes einzelne Vorkommen von $gesehen ab, baue ein neues Array @noch_nicht_gesehen und joine mir daraus den String $ergebnis. Das funktioniert, scheint mir aber ein sehr umständliches Vorgehen zu sein.
Es gibt bestimmt einen eleganten regulären Ausdruck, der das viel schneller und mit viel weniger Code erledigen kann. Ich habe nur leider keinen Ansatzpunkt, wie der aussehen könnte. Hat jemand eine Idee?
Optimierende Grüße
JOhnnY
Es gibt bestimmt einen eleganten regulären Ausdruck, der das viel schneller und mit viel weniger Code erledigen kann. Ich habe nur leider keinen Ansatzpunkt, wie der aussehen könnte. Hat jemand eine Idee?
Regex sind nicht immer besser. Ich würde genauso zu Hashkey Lookups tendieren.
Achte auf \Q \E!
#!perl
use warnings;
use strict;
my $all = 'a b c d e f';
my $seen= 'a c';
my $result = $all;
foreach( split/\s+/, $seen ){
$result =~ s/\Q$_\E(\s+|$)//;
}
print $result, "\n";
<>;
exit;
mfg Beat
Hallo Beat,
Regex sind nicht immer besser. Ich würde genauso zu Hashkey Lookups tendieren.
--- warum? Die RegEx-Lösung sieht doch schmaler aus?! Danke dafür!
Ich hatte zwar noch etwas weiter gedacht, etwa so:
$resultat = $alle.'|'.$gesehen;
$resultat =~ s/(nimm erste Zahl hinter '|' und lösche sie vor '|')//;
Aber das ist dann vielleicht auch wieder zu verwurschtelt, wenn es überhaupt so geht. Ich habe gelesen, daß sich RegEx Ausdrücke merken kann und diese auf sich selbst anwenden. Da dachte ich vielleicht geht das -schwuuuups- in einer Zeile...
Achte auf \Q \E!
--- sonst wird $_ nicht korrekt interpretiert?
print $result, "\n";
<>;
exit;
--- was soll denn <>; bewirken?
Gerexten Gruß
JOhnnY
Achte auf \Q \E!
--- sonst wird $_ nicht korrekt interpretiert?
m/$eviluserinput/
\Q maskiert Zeichen mit spezieller Bedeutung.
print $result, "\n";
<>;
exit;
--- was soll denn <>; bewirken?
Och, du bekommst die Eingabeaufforderung und siehst dadurch den printout in der vorangehenden Zeile.
mfg Beat
Hallo,
ob es schneller geht, solltest du selbst herausfinden.
Weniger geht immer, z.B.:
warn join(" ", grep !{map(($_ => 1), split/\s+/, $seen)}->{$_}, split/\s+/, $all);
allerdings würde ich dringend zu einer lesbaren variante raten, die ohne kommentare auskommt!
hth
Hallo hth,
warn join(" ", grep !{map(($_ => 1), split/\s+/, $seen)}->{$_}, split/\s+/, $all);
--- upmh. Das ist es, warum ich Perl so liebe. TMTOWTDI. Manche dieser Wege sind schlicht ehrfurchtgebietend.
allerdings würde ich dringend zu einer lesbaren variante raten, die ohne kommentare auskommt!
--- yepp. Ich glaube, meine ursprüngliche Idee war doch gar nicht so umständlich, zumindest ist sie leicht zu verstehen.
Danke Dir
JOhnnY
Nein, man bearbeitet Mengen nicht mit regulären Ausdrücken.
use Set::Scalar qw();
say Set::Scalar->new(
qw(1 2 3 5 6 7 8 9 10 11 12)
)->delete(Set::Scalar->new(
qw(6 11 1)
));
__END__
(1 10 11 12 2 3 5 6 7 8 9)
Hallo CPAN!
say
Du setzt aber hier voraus, dass Perl 5.10.0 (und feature.pm eingebunden ist) vorhanden ist, was zwar lokal vorhanden sein sollte, bei den lieben Providern aber noch keinen Einzug gefunden hat..., falls die OPs ihre Skripte dort laufen lassen wollen.
Viele Grüße aus Frankfurt/Main,
Patrick