Submatches von s/// verarbeiten
Submatches von s/// verarbeiten
am 15.11.2006 23:32:28 von Frank Seitz
Hallo,
ich habe eine Substitution mit einem Regex $reg:
$str =~ s/$reg//;
$reg enthält eine unbekannte Anzahl an Submatches
(...), die ich im Anschluss verarbeiten möchte.
Wie mache ich das am besten? Die Variablen $1, $2 usw.
nützen mir dabei wohl nicht nicht viel.
Hat jemand eine Idee?
Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel
Re: Submatches von s/// verarbeiten
am 16.11.2006 00:33:48 von Alexander Bartolich
Frank Seitz schrieb:
> [...]
> $reg enthält eine unbekannte Anzahl an Submatches
> (...), die ich im Anschluss verarbeiten möchte.
> Wie mache ich das am besten? Die Variablen $1, $2 usw.
> nützen mir dabei wohl nicht nicht viel.
man perlvar
# [...]
# You can use $#+ to determine how many subgroups were in the
# last successful match.
# [...]
# $1 is the same as "substr($var, $-[1], $+[1] - $-[1])"
# $2 is the same as "substr($var, $-[2], $+[2] - $-[2])"
# $3 is the same as "substr($var, $-[3], $+[3] - $-[3])"
--
Re: Submatches von s/// verarbeiten
am 16.11.2006 00:53:33 von Frank Seitz
Alexander Bartolich wrote:
> Frank Seitz schrieb:
>>[...]
>>$reg enthält eine unbekannte Anzahl an Submatches
>>(...), die ich im Anschluss verarbeiten möchte.
>>Wie mache ich das am besten? Die Variablen $1, $2 usw.
>>nützen mir dabei wohl nicht nicht viel.
>
> man perlvar
> # [...]
> # You can use $#+ to determine how many subgroups were in the
> # last successful match.
> # [...]
> # $1 is the same as "substr($var, $-[1], $+[1] - $-[1])"
> # $2 is the same as "substr($var, $-[2], $+[2] - $-[2])"
> # $3 is the same as "substr($var, $-[3], $+[3] - $-[3])"
Das geht so direkt nicht. Da $var durch die Substitution
verändert wird, sind die Indizes nicht mehr gültig.
Ich könnte den Wert von $var natürlich kopieren.
Irgendwie macht mich der Vorschlag nicht glücklich.
Mir ist zwischenzeitlich dies hier eingefallen,
das ist zumindest halbwegs kurz:
if (my @mat = $str =~ /$reg/)
{
$str =~ s/$reg//;
# @mat verarbeiten
}
Vielleicht hat ja jemand noch eine bessere Idee.
Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel
Re: Submatches von s/// verarbeiten
am 16.11.2006 09:04:20 von Christian Winter
Frank Seitz schrieb:
> Alexander Bartolich wrote:
>> Frank Seitz schrieb:
>>> [...]
>>> $reg enthält eine unbekannte Anzahl an Submatches
>>> (...), die ich im Anschluss verarbeiten möchte.
>>> Wie mache ich das am besten? Die Variablen $1, $2 usw.
>>> nützen mir dabei wohl nicht nicht viel.
>> man perlvar
>> # [...]
>> # You can use $#+ to determine how many subgroups were in the
>> # last successful match.
>> # [...]
>> # $1 is the same as "substr($var, $-[1], $+[1] - $-[1])"
>> # $2 is the same as "substr($var, $-[2], $+[2] - $-[2])"
>> # $3 is the same as "substr($var, $-[3], $+[3] - $-[3])"
>
> Das geht so direkt nicht. Da $var durch die Substitution
> verändert wird, sind die Indizes nicht mehr gültig.
> Ich könnte den Wert von $var natürlich kopieren.
> Irgendwie macht mich der Vorschlag nicht glücklich.
>
> Mir ist zwischenzeitlich dies hier eingefallen,
> das ist zumindest halbwegs kurz:
>
> if (my @mat = $str =~ /$reg/)
> {
> $str =~ s/$reg//;
> # @mat verarbeiten
> }
>
> Vielleicht hat ja jemand noch eine bessere Idee.
Besser? Keine Ahnung. Anders? Ja.
if( $str =~ s/$reg// )
{
@mat = map { $$_ } 0 .. $#+;
}
-Christian
Re: Submatches von s/// verarbeiten
am 16.11.2006 09:21:08 von Daniel Fischer
Christian Winter!
> Besser? Keine Ahnung. Anders? Ja.
>
> if( $str =~ s/$reg// )
> {
> @mat = map { $$_ } 0 .. $#+;
> }
Das ist speziell dann nicht besser, wenn $0 der Pfad des Scripts ist. ;-)
Und man kann es noch in ein Statement schreiben, aber dann ist es
definitiv nicht mehr besser ;-)
Gruß
Daniel
Re: Submatches von s/// verarbeiten
am 16.11.2006 09:55:35 von Frank Wiegand
Frank Seitz schrieb:
> if (my @mat = $str =~ /$reg/)
> {
> $str =~ s/$reg//;
> # @mat verarbeiten
> }
>
> Vielleicht hat ja jemand noch eine bessere Idee.
{
no strict 'refs';
$str =~ s/$reg/@mat=grep defined,map$$_,1..32;''/e;
}
Für gewisse Werte von »besser«.
Frank
Re: Submatches von s/// verarbeiten
am 16.11.2006 10:00:25 von Christian Winter
Daniel Fischer schrieb:
> Christian Winter!
>> Besser? Keine Ahnung. Anders? Ja.
>>
>> if( $str =~ s/$reg// )
>> {
>> @mat = map { $$_ } 0 .. $#+;
>> }
>
> Das ist speziell dann nicht besser, wenn $0 der Pfad des Scripts ist. ;-)
>
> Und man kann es noch in ein Statement schreiben, aber dann ist es
> definitiv nicht mehr besser ;-)
Arghl. Ich geb's ja zu, aus der Hüfte nach hinten geschossen
und mitten durch die Brust ins Knie getroffen.
Aber der Einzeiler hätte schon was golfiges.
my @mat = map { $$_ } 1 .. $#+ if( $str =~ s/$reg// );
-Christian
Re: Submatches von s/// verarbeiten
am 16.11.2006 10:10:27 von Frank Seitz
Christian Winter wrote:
> Aber der Einzeiler hätte schon was golfiges.
>
> my @mat = map { $$_ } 1 .. $#+ if( $str =~ s/$reg// );
Die runden Klammern kannst Du noch weglassen.
Allerdings fehlt das "no strict 'refs'", das in
einer ordentlichen Umgebung wegen der Symbolic Reference
erforderlich ist.
Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel
Re: Submatches von s/// verarbeiten
am 16.11.2006 11:14:58 von Mirco Wahab
Frank Seitz schrieb:
> ich habe eine Substitution mit einem Regex $reg:
>
> $str =~ s/$reg//;
>
> $reg enthält eine unbekannte Anzahl an Submatches
> (...), die ich im Anschluss verarbeiten möchte.
> Wie mache ich das am besten? Die Variablen $1, $2 usw.
> nützen mir dabei wohl nicht nicht viel.
> Hat jemand eine Idee?
Hallo Frank,
kannst du mal ein konkretes kleines
"Workflow"-Beispiel dazu, vielleicht mit
einer Regex und ein paar Daten angeben?
Deine Beschreibungen sind mir zu abstrakt ;-)
Viele Grüße
M. Wahab
Re: Submatches von s/// verarbeiten
am 16.11.2006 13:32:16 von Frank Seitz
Mirco Wahab wrote:
> Frank Seitz schrieb:
>
>>ich habe eine Substitution mit einem Regex $reg:
>>
>> $str =~ s/$reg//;
>>
>>$reg enthält eine unbekannte Anzahl an Submatches
>>(...), die ich im Anschluss verarbeiten möchte.
>>Wie mache ich das am besten? Die Variablen $1, $2 usw.
>>nützen mir dabei wohl nicht nicht viel.
>>Hat jemand eine Idee?
>
> Hallo Frank,
>
> kannst du mal ein konkretes kleines
> "Workflow"-Beispiel dazu, vielleicht mit
> einer Regex und ein paar Daten angeben?
>
> Deine Beschreibungen sind mir zu abstrakt ;-)
Es sollte Dir zu denken geben, dass andere diese
Verständnisschwierigkeiten haben :)
Mein konkreter Anwendungsfall ist zu kompliziert, um
ihn hier zu erklären. Das folgende Beispiel ist
aus den Fingern gesogen:
#---------------------------------------------
#!/usr/local/bin/perl -w
use strict;
# Beispielstring, Beispielregex (mit 2 Submatches)
my $str = 'a b c=d e';
my $reg = qr/(\w+)=(\w+)/;
# Liefere die Werte der Submatches, ohne
# die Anzahl vorab zu kennen
if ($str =~ s/$reg//)
{
no strict 'refs';
my @mat = map { $$_ } 1 .. $#+;
print "@mat\n";
}
__END__
c d
#---------------------------------------------
Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel
Re: Submatches von s/// verarbeiten
am 16.11.2006 14:02:52 von Mirco Wahab
Frank Seitz schrieb:
> Mirco Wahab wrote:
>> Frank Seitz schrieb:
>>> ich habe eine Substitution mit einem Regex $reg:
>>> $str =~ s/$reg//;
>> Deine Beschreibungen sind mir zu abstrakt ;-)
> Es sollte Dir zu denken geben, dass andere diese
> Verständnisschwierigkeiten haben :)
> ... ... Das folgende Beispiel ist
> aus den Fingern gesogen:
>
OK, ich bin schon mal auch schwer von Begriff.
Dein Szenario lies imho noch zu vieles offen ...
Vielleicht würde ich das so machen:
use strict;
use warnings;
use re 'eval';
my $str = 'a b c=d e'; # Beispielstring, Beispielregex (mit 2 Submatches)
my $acc = '(?{push @mat, map +(substr($str,$-[$_],$+[$_]-$-[$_]) ), 1..-1+@+ })';
my $reg = qr/(\w+)=(\w+)/x;
my @mat = ();
$str =~ s/$reg$acc//g;
print scalar @mat, "\n@mat\n";
also einen "Akkumulator" verwenden.
Viele Grüße
Mirco
Re: Submatches von s/// verarbeiten
am 17.11.2006 00:22:50 von Olaf Schneider
Frank Seitz wrote:
> ich habe eine Substitution mit einem Regex $reg:
> $str =~ s/$reg//;
> $reg enthält eine unbekannte Anzahl an Submatches
> (...), die ich im Anschluss verarbeiten möchte.
> Wie mache ich das am besten? Die Variablen $1, $2 usw.
> nützen mir dabei wohl nicht nicht viel.
> Hat jemand eine Idee?
$str="ab11bcde12n42nn";
while($str =~s/(\d\d)//) {
print "$1\n"
}
print "$str\n";'
liefert:
11
12
42
abbcdennn
Kennt jemand die Stelle in der Doku, wo dieses Verhalten
erklärt bzw. beschrieben ist?
Re: Submatches von s/// verarbeiten
am 17.11.2006 09:28:23 von Christian Winter
Olaf Schneider schrieb:
> $str="ab11bcde12n42nn";
> while($str =~s/(\d\d)//) {
> print "$1\n"
> }
> print "$str\n";'
>
> liefert:
>
> 11
> 12
> 42
> abbcdennn
>
> Kennt jemand die Stelle in der Doku, wo dieses Verhalten
> erklärt bzw. beschrieben ist?
Welches "Verhalten" meinst Du?
-Christian
Re: Submatches von s/// verarbeiten
am 17.11.2006 10:10:33 von Frank Seitz
Christian Winter wrote:
> Olaf Schneider schrieb:
>>
>>$str="ab11bcde12n42nn";
>>while($str =~s/(\d\d)//) {
>> print "$1\n"
>>}
>>print "$str\n";'
>>
>>liefert:
>>
>>11
>>12
>>42
>>abbcdennn
>>
>>Kennt jemand die Stelle in der Doku, wo dieses Verhalten
>>erklärt bzw. beschrieben ist?
>
> Welches "Verhalten" meinst Du?
Ja, was überrascht Dich an dem Ergebnis?
Beachte, dass s/// nicht nur matcht, sondern das Gematchte
substituiert, und zwar in dem Fall durch nichts (Leerstring).
Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel
Re: Submatches von s/// verarbeiten
am 17.11.2006 18:58:04 von Olaf Schneider
Frank Seitz wrote:
> Christian Winter wrote:
>> Olaf Schneider schrieb:
>>>while($str =~s/(\d\d)//) {
>>>Kennt jemand die Stelle in der Doku, wo dieses Verhalten
>>>erklärt bzw. beschrieben ist?
>>
>> Welches "Verhalten" meinst Du?
Ok, beim genaueren Nachdenken ist es nicht mehr überraschend.
Mir erschien diese Floskel gestern abend aber so elegant, daß
ich irgendeine Magie dahinter vermutet habe. [1]
> Ja, was überrascht Dich an dem Ergebnis?
Mich wundert jetzt nur, daß Du als Poster von:
| ich habe eine Substitution mit einem Regex $reg:
|
| $str =~ s/$reg//;
|
| $reg enthält eine unbekannte Anzahl an Submatches
| (...), die ich im Anschluss verarbeiten möchte.
| Wie mache ich das am besten? Die Variablen $1, $2 usw.
| nützen mir dabei wohl nicht nicht viel.
| Hat jemand eine Idee?
nicht überrascht bist. Schließlich wollest Du doch genau
sowas.
[1] Und auch ohne Magie wäre es schön, so ein Beispiel
in der Doku zu finden.
Re: Submatches von s/// verarbeiten
am 17.11.2006 19:32:04 von Frank Seitz
Olaf Schneider wrote:
> Mich wundert jetzt nur, daß Du als Poster von:
>
> | ich habe eine Substitution mit einem Regex $reg:
> |
> | $str =~ s/$reg//;
> |
> | $reg enthält eine unbekannte Anzahl an Submatches
> | (...), die ich im Anschluss verarbeiten möchte.
> | Wie mache ich das am besten? Die Variablen $1, $2 usw.
> | nützen mir dabei wohl nicht nicht viel.
> | Hat jemand eine Idee?
>
> nicht überrascht bist. Schließlich wollest Du doch genau
> sowas.
Nein, bei meiner Frage ging es um etwas anderes:
Ich habe Substitutions-Regexes mit nicht nur einem,
sondern mit mehreren Subausdrücken (...) und möchte die Werte
aller Submatches haben. Das ist etwas anderes als
eine Substitution mehrfach anzuwenden.
Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel
Re: Submatches von s/// verarbeiten
am 17.11.2006 23:31:19 von Olaf Schneider
Frank Seitz wrote:
> Ich habe Substitutions-Regexes mit nicht nur einem,
> sondern mit mehreren Subausdrücken (...) und möchte die Werte
> aller Submatches haben. Das ist etwas anderes als
> eine Substitution mehrfach anzuwenden.
Meinst Du mit "Submatches" das was in der Doku zu m// als
"subexpressions matched by the parentheses" umschrieben ist?
Für sowas ist doch die Einbettung von Code in den Regex gedacht:
$str="foo a1 b17 x509 bar";
$str=~s/(?:\s*\b([a-z]\d+)\b\s*(?{print "$^N\n"}))+//;
print "$str\n";'
ergibt:
a1
b17
x509
foobar
Zugegebenermaßen sind die (?{}) assertions experimentell
(zumindest in meinem Perl 5.8.0 hier).
Re: Submatches von s/// verarbeiten
am 18.11.2006 09:16:37 von Frank Seitz
Olaf Schneider wrote:
> Frank Seitz wrote:
>>
>>Ich habe Substitutions-Regexes mit nicht nur einem,
>>sondern mit mehreren Subausdrücken (...) und möchte die Werte
>>aller Submatches haben. Das ist etwas anderes als
>>eine Substitution mehrfach anzuwenden.
>
> Meinst Du mit "Submatches" das was in der Doku zu m// als
> "subexpressions matched by the parentheses" umschrieben ist?
Vermutlich ja (ich habe das jetzt nicht nachgelesen).
> Für sowas ist doch die Einbettung von Code in den Regex gedacht:
>
> $str="foo a1 b17 x509 bar";
> $str=~s/(?:\s*\b([a-z]\d+)\b\s*(?{print "$^N\n"}))+//;
> print "$str\n";'
>
> ergibt:
>
> a1
> b17
> x509
> foobar
>
> Zugegebenermaßen sind die (?{}) assertions experimentell
> (zumindest in meinem Perl 5.8.0 hier).
Den Weg hat Mirco Wahab auch schon vorgeschlagen.
Der ist mir aber zu umständlich.
Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel