Anzahl und Reihenfolge in perl regex

hwj

Doppel-As
Beiträge
131
... oder auch die Denksportaufgabe für's Wochenende :devil:

Guten Morgen !

Ich versuche mich gerade an einem Suchen/Ersetzen Ausdruck in perl und frage mich gerade, ob das mit regex überhaupt noch geht ... also, ich würde gerne einen String mit "Attribut=Wert" ersetzen, aber jedes Attribut darf nur max. 1x vorkommen, aber die Reihenfolge soll egal sein. Klingt einfach, aber geht das ?

Beispiel:

ok: Red=123 green=34 blue=45
ok: green=56 Red=123
ok: blue=5

nicht ok (2x red): red=4 blue=5 red=5

sicher könnte man schreiben:
Code:
sub mymatch {
my $str = shift;

if   ($str =~ /(red=\d+)? (green=\d+)? (blue=\d+)?/) {
  ...
} elsif ($str =~ /(red=\d+)? (blue=\d+)? (green=\d+)?/) {
  ...
} elsif ($str =~ /(green=\d+)? (blue=\d+)? (red=\d+)?/) {
 ...

und so alle Kombinationen abklappern, aber nicht gerade elegant. Und wenn dann noch eine weitere Farbe (bzw. Attribut) hinzukommt ...

Eine andere Möglichkeit wäre natürlich, die Regex im Programm als String selbst zu erzeugen und dann evtl. eval zu arbeiten, oder ?

Geht das einfacher ?

Gruss
Heiko
 

angelsfall

Routinier
Beiträge
315
hi, mir ist nicht ganz klar, was du machen willst, da du zu wenig informationen gegeben hast. so wie es sich anhört, könnte man das problem auch ganz anders lösen, oder sollen es explizit regex sein? wo z.b. kriegst du die informationen her, welche farbe wie geändert werden soll?

ich hätte da einen anderen lösungsansatz, der mir aber auch noch nich so gefällt ;) aber das übt schließlich.
ich bin davon ausgegangen, dass du nen hash hast, in dem die benötigten informationen stehen:

Code:
#!/usr/bin/perl -wl

use strict;
use warnings;

# your string with color information
my $str = "red=100 green=200 blue=300";

# hash with replace content
my %ch = ( 
  'red' => 210,
  'blue' => 400,
);

# turn str into hash
my %hash = map { split "=", $_ } split " ", $str;

# merge hashes. this updates the values or add new key-value if key doesnt exists
%hash = (%hash, %ch);

# join hash to string again
$str = join " ", map { $_ . "=" . $hash{$_} } keys %hash;

print $str;

wenn ich dich falsch verstanden habe, tut mir das leid. vielleicht hilfts aber :)

/edit: schwere fehler im code behoben ;) jaja, es ist spät. und mir ist auch bewusst, das die werte fuer die farben nur bis 255 gehen :)
 
Zuletzt bearbeitet:

Xanti

Mouse Organist
Beiträge
1.855
Man könnte mit

Code:
@red = (/(red=\d+/g));
$c_red = $#red+1;
...

das Vorkommen zählen und dann auf kleinergleich 1 testen.

Gruss, Xanti
 

hwj

Doppel-As
Beiträge
131
Hallo Ihr beiden,

danke für die Tipps. Eine regex ist mir auch über das Wochenende nicht eingefallen. In der Eingabedatei stehen mehrere Zeilen mit "red .. green .. blue" - und eine "gedachte" Ausgabe wäre z.B. eine Komma-separierte Liste aller Farbwerte ( "-" für nicht angegeben).

Ich denke, ich mach' das doch Zeilenweise "zu Fuß" - ist unterm Strich auch nach einfacher, wenn man später den Code noch mal ändern muß.

Heiko
 

szk

Grünschnabel
Beiträge
6
Vorschlag:

Code:
sub mymatch {
my $str = shift;

if   ($str !~ /(\w+=).*(\1)/)  # Doppelte verbieten
{
  if (%_ = ($str =~ /(\w)=(\d+)/g)) # Attribut=Wert - Liste erstellen
  {

    # Hash %_ irgendwie verarbeiten:

    foreach $key (sort keys %_)
    {
       print "$key=".$_{$key}."\n";
       #...
    };
  };
} else {
  # Attribut doppelt
}; 

}
 

hwj

Doppel-As
Beiträge
131
Hallo Sebastian,

ja, so in der Art habe ich das jetzt auch am laufen. Doch was ist das:
Code:
if (%_ = ($str =~ /(\w)=(\d+)/g))

Cool, man lernt ja nie aus - aus einem Match direkt in einen Hash, ist ja nicht wahr. und dann noch in einer if-Abfrage ... wird wohl Zeit mir mal wieder ein neues Perl-Handbuch zu kaufen :-)

Danke
Heiko
 

Ähnliche Themen

Displayport + externer Monitor zeigt bei startx nichts erst bei DVI

Int nach Zeichenkette str in Binaerdarstellung

Externe Medien nicht mountbar

Oben