Thread View: pl.comp.lang.perl
11 messages
11 total messages
Started by ..:: sjf ::..
Wed, 06 Jan 2010 19:21
Walidacja wyrażenia regularnego - operatory =~ i !~ jako zmienna
Author: ..:: sjf ::..
Date: Wed, 06 Jan 2010 19:21
Date: Wed, 06 Jan 2010 19:21
60 lines
2534 bytes
2534 bytes
Witam,
Potrzebuję w skrypcie funkcjonalności filtrowania danych z
wykorzystaniem RE podanego jako opcja do programu, ale z możliwością
podania zanegowanego RE. Założyłem, że RE poprzedzony przez ! będzie
traktowany jako zanegowany oraz odpowiednie zastosowanie operatorów =~ i !~.
Niestety sprawdzenie wyniku eval - w wierszu oznaczonym *) na poniższym
listingu - nie wiele daje, gdyż za każdym razem warunek jest spełniony.
v+
my $re_oper;
if ($opt{g}) {
if ($opt{g} =~ /^!(.+)$/) {
$re_oper = "!~";
$opt{g} = $1;
}
else {
$re_oper = "=~";
}
eval { $opt{g} = qr/$opt{g}/ };
die "** Error in RE \"$opt{g}\":\n$@\n" if $@;
}
foreach (<DATA>) {
my($host) = /\s*\S+\s+(\S+)/;
if ($opt{g}) {
my $expr = "$host $re_oper $opt{g}";
if ( 1 == eval $expr ) { # *)
warn "** match \"$opt{g}\" [ $re_oper ] in \"$host\"\n";
print "$host\n";
}
}
else {
print "$host\n";
}
}
v-
Program wykorzystujący analogiczną funkcjonalność eval-a , ale z
operatorami arytmetycznymi działa poprawnie:
v+
@op = ('+', '-', '*', '/');
for $a(@op) {
for $b(@op) {
for $c(@op) {
for $d(@op) {
$_ = "1${a}2${b}3${c}4${d}5";
print "$_\n" if 20 == eval $_;
}
}
}
}
v-
W jaki sposób przerobić mój program, aby możliwe było wykorzystanie
dopasowania RE i zanegowanego RE?
--
Szczepan J. Fijał :: sjf @ 50°07'N 18°58'E
xmpp:sjf@jabster.pl | tlen:sjf | gg:2604451 | skype:s.fijal?call
"Linux is like Wigwam. No gates, no windows... Apache inside ;-)"
Re: Walidacja wyrażenia regularnego - operatory =~ i !~ jako zmienna
Author: Szymon Sokół
Date: Wed, 06 Jan 2010 19:42
Date: Wed, 06 Jan 2010 19:42
15 lines
1724 bytes
1724 bytes
On Wed, 06 Jan 2010 20:21:04 +0100, ..:: sjf ::.. wrote:
> foreach (<DATA>) {
> my($host) = /\s*\S+\s+(\S+)/;
Jaką wartość ma w tym miejscu $host...
> if ($opt{g}) {
> my $expr = "$host $re_oper $opt{g}";
...i jaką w rezultacie ma tu $expr?
--
Szymon Sokół (SS316-RIPE) -- Network Manager B
Computer Center, AGH - University of Science and Technology, Cracow, Poland O
http://home.agh.edu.pl/szymon/ PGP key id: RSA: 0x2ABE016B, DSS: 0xF9289982 F
Free speech includes the right not to listen, if not interested -- Heinlein H
Re: Walidacja wyrażenia regularnego - operatory =~ i !~ jako zmienna
Author: Tomasz "rocku" K.
Date: Wed, 06 Jan 2010 19:45
Date: Wed, 06 Jan 2010 19:45
24 lines
1496 bytes
1496 bytes
..:: sjf ::.. pisze:
> ...
> W jaki sposób przerobić mój program, aby możliwe było wykorzystanie
> dopasowania RE i zanegowanego RE?
Po co w ogóle stosować eval przy wierszu z gwiazdka? Możesz określić na
początku czy stosować wersje zanegowaną czy nie, a później:
if ($neg) {
$host !~ $opt{g}
} else {
$host =~ $opt{g}
}
Odnośnie samej operacji z evalowaniem wyrażenia, w tym przypadku zdaje
się działać poprawnie:
$ perl -e '$r=q|"foo" !~ /v/|; print (1 == eval $r ? "true\n" : "false\n")'
true
$ perl -e '$r=q|"foo" =~ /v/|; print (1 == eval $r ? "true\n" : "false\n")'
false
--
Pozdrawiam,
Tomasz "rocku" K.
Re: Walidacja wyrażenia regularnego - operatory =~ i !~ jako zmienna
Author: ..:: sjf ::..
Date: Wed, 06 Jan 2010 20:24
Date: Wed, 06 Jan 2010 20:24
18 lines
1546 bytes
1546 bytes
W dniu 2010-01-06 20:42, Szymon Sokół pisze:
> On Wed, 06 Jan 2010 20:21:04 +0100, ..:: sjf ::.. wrote:
>
>> foreach (<DATA>) {
>> my($host) = /\s*\S+\s+(\S+)/;
> Jaką wartość ma w tym miejscu $host...
>
taką jak $1?
>> if ($opt{g}) {
>> my $expr = "$host $re_oper $opt{g}";
> ...i jaką w rezultacie ma tu $expr?
myślę, że w związku z powyższym tego już nie muszę wyjaśniać...
--
Szczepan J. Fijał :: sjf @ 50°07'N 18°58'E
xmpp:sjf@jabster.pl | tlen:sjf | gg:2604451 | skype:s.fijal?call
"Linux is like Wigwam. No gates, no windows... Apache inside ;-)"
Re: Walidacja wyrażenia regularnego - operatory =~ i !~ jako zmienna
Author: ..:: sjf ::..
Date: Wed, 06 Jan 2010 20:34
Date: Wed, 06 Jan 2010 20:34
31 lines
2024 bytes
2024 bytes
W dniu 2010-01-06 20:45, Tomasz "rocku" K. pisze:
> ..:: sjf ::.. pisze:
>> ...
>> W jaki sposób przerobić mój program, aby możliwe było wykorzystanie
>> dopasowania RE i zanegowanego RE?
>
> Po co w ogóle stosować eval przy wierszu z gwiazdka? Możesz określić na
> początku czy stosować wersje zanegowaną czy nie, a później:
> if ($neg) {
> $host !~ $opt{g}
> } else {
> $host =~ $opt{g}
> }
>
Wiem, od tego zacząłem. Ale zaciekawił mnie sposób z przypisaniem
operatorów do zmiennej, który w tym przypadku nie bardzo działa.
> Odnośnie samej operacji z evalowaniem wyrażenia, w tym przypadku zdaje
> się działać poprawnie:
>
> $ perl -e '$r=q|"foo" !~ /v/|; print (1 == eval $r ? "true\n" : "false\n")'
> true
> $ perl -e '$r=q|"foo" =~ /v/|; print (1 == eval $r ? "true\n" : "false\n")'
> false
>
Tak, w ten sposób działa - podobnie testowałem.
--
Szczepan J. Fijał :: sjf @ 50°07'N 18°58'E
xmpp:sjf@jabster.pl | tlen:sjf | gg:2604451 | skype:s.fijal?call
"Linux is like Wigwam. No gates, no windows... Apache inside ;-)"
Re: Walidacja wyrażenia regularnego - operatory =~ i !~ jako zmienna
Author: Szymon Sokół
Date: Wed, 06 Jan 2010 21:07
Date: Wed, 06 Jan 2010 21:07
23 lines
2168 bytes
2168 bytes
On Wed, 06 Jan 2010 21:34:05 +0100, ..:: sjf ::.. wrote: > W dniu 2010-01-06 20:45, Tomasz "rocku" K. pisze: [----] >> Odnośnie samej operacji z evalowaniem wyrażenia, w tym przypadku zdaje >> się działać poprawnie: >> >> $ perl -e '$r=q|"foo" !~ /v/|; print (1 == eval $r ? "true\n" : "false\n")' >> true >> $ perl -e '$r=q|"foo" =~ /v/|; print (1 == eval $r ? "true\n" : "false\n")' >> false >> > Tak, w ten sposób działa - podobnie testowałem. ...z czego łatwo wywnioskować, że sama konstrukcja jest w porządku, a problem leży w Twoich konkretnych danych. A na moje pytanie o te dane udzieliłeś odpowiedzi, którą przy maksimum dobrej woli mogę nazwać wymijającą. -- Szymon Sokół (SS316-RIPE) -- Network Manager B Computer Center, AGH - University of Science and Technology, Cracow, Poland O http://home.agh.edu.pl/szymon/ PGP key id: RSA: 0x2ABE016B, DSS: 0xF9289982 F Free speech includes the right not to listen, if not interested -- Heinlein H
Re: Walidacja wyrażenia regularnego - operatory =~ i !~ jako zmienna
Author: ..:: sjf ::..
Date: Thu, 07 Jan 2010 21:27
Date: Thu, 07 Jan 2010 21:27
61 lines
2927 bytes
2927 bytes
W dniu 2010-01-06 20:42, Szymon Sokół pisze:
> On Wed, 06 Jan 2010 20:21:04 +0100, ..:: sjf ::.. wrote:
>
>> foreach (<DATA>) {
>> my($host) = /\s*\S+\s+(\S+)/;
> Jaką wartość ma w tym miejscu $host...
>
>> if ($opt{g}) {
>> my $expr = "$host $re_oper $opt{g}";
> ...i jaką w rezultacie ma tu $expr?
>
Ok, podrzucę trochę przykładowych danych - powinno to rzucić więcej
światła na problem:
sekcja __DATA__ w skrypcie:
v+
10.19.171.25 ww_w121
10.19.171.17 ww_w122
10.19.171.24 ww_w123
10.19.171.150 kt_e111
10.19.171.148 kt_e112
10.19.171.149 kt_e113
10.19.171.5 pz_w101
10.19.171.6 pz_w103
10.19.171.7 gd_e111
10.19.171.75 gd_e121
10.19.171.76 wr_e121
10.19.171.77 wr_w103
10.19.171.6 gd_w101
10.19.171.4 pz_e121
10.19.171.5 wr_w101
10.19.171.10 gd_w102
10.19.171.4 wr_e111
10.19.171.5 wr_w102
v-
Przykład 1) Skrypt uruchomiono z opcją -g = "kt_", tak więc w wyniku
powinienem otrzymać:
kt_e111
kt_e112
kt_e113
Przykład 2) Skrypt uruchomiony z opcją -g = "!ww_" powinien w rezultacie
wypisać wszystkie powyższe nazwy (z sekcji DATA) poza ww_w121, ww_w122,
ww_w123.
W przypadku zastosowania sposobu z testowaniem czy RE "normalny" czy
zanegowany i odpowiednim ustawieniem zmiennej - podobnie jak
zaproponował Tomasz "rocku" K. - działa w porządku. Niestety w
rzeczywistości opcja g składa się z kilku RE oddzielonych za pomocą
przecinka - taką założyłem składnię - z których każdy ma zostać
dopasowany do nazw z listy jako logiczny AND.
Czyli przykład 3) Uruchomienie z opcją g = "!ww_,!kt_", w zamierzeniu
chcę otrzymać listę wszystkich hostów z __DATA__ poza ww_w121, ww_w122,
ww_w123, kt_e111, kt_e112, kt_e113.
--
Szczepan J. Fijał :: sjf @ 50°07'N 18°58'E
xmpp:sjf@jabster.pl | tlen:sjf | gg:2604451 | skype:s.fijal?call
"Linux is like Wigwam. No gates, no windows... Apache inside ;-)"
Re: Walidacja wyrażenia regularnego - operatory =~ i !~ jako zmienna
Author: Szymon Sokół
Date: Thu, 07 Jan 2010 22:34
Date: Thu, 07 Jan 2010 22:34
42 lines
2901 bytes
2901 bytes
On Thu, 07 Jan 2010 22:27:23 +0100, ..:: sjf ::.. wrote:
> W przypadku zastosowania sposobu z testowaniem czy RE "normalny" czy
> zanegowany i odpowiednim ustawieniem zmiennej - podobnie jak
> zaproponował Tomasz "rocku" K. - działa w porządku. Niestety w
> rzeczywistości opcja g składa się z kilku RE oddzielonych za pomocą
> przecinka - taką założyłem składnię - z których każdy ma zostać
> dopasowany do nazw z listy jako logiczny AND.
>
> Czyli przykład 3) Uruchomienie z opcją g = "!ww_,!kt_", w zamierzeniu
> chcę otrzymać listę wszystkich hostów z __DATA__ poza ww_w121, ww_w122,
> ww_w123, kt_e111, kt_e112, kt_e113.
No to to już nie jest takie do końca trywialne, najprościej pewnie będzie
podzielić te regexpy na dwie grupy - zanegowane i niezanegowane - a potem
obrabiać osobno. Ja bym to zrobił jakoś tak:
my(@positive, @negative);
for my $re (split /,/, $opt{g}) {
if($re =~ s/^!//) {
push @negative, $re;
} else {
push @positive, $re;
}
my $p_re = join '|', @positive;
eval { $p_re = qr/$p_re/; }
die "** Error in RE \"$p_re\":\n$@\n" if $@;
my $n_re = join '|', @negative;
eval { $n_re = qr/$n_re/; }
die "** Error in RE \"$n_re\":\n$@\n" if $@;
foreach (<DATA>) {
my($host) = /\s*\S+\s+(\S+)/;
print "$host\n"
unless @negative and $host =~ $n_re
or @positive and $host !~ $p_re; # z prawa de Morgana
}
--
Szymon Sokół (SS316-RIPE) -- Network Manager B
Computer Center, AGH - University of Science and Technology, Cracow, Poland O
http://home.agh.edu.pl/szymon/ PGP key id: RSA: 0x2ABE016B, DSS: 0xF9289982 F
Free speech includes the right not to listen, if not interested -- Heinlein H
Re: Walidacja wyrażenia regularnego - operatory =~ i !~ jako zmienna
Author: Maciej Misiak
Date: Wed, 13 Jan 2010 14:17
Date: Wed, 13 Jan 2010 14:17
15 lines
1431 bytes
1431 bytes
..:: sjf ::.. pisze:
> W dniu 2010-01-06 20:42, Szymon Sokół pisze:
>> On Wed, 06 Jan 2010 20:21:04 +0100, ..:: sjf ::.. wrote:
>>
>>> if ($opt{g}) {
>>> my $expr = "$host $re_oper $opt{g}";
>> ...i jaką w rezultacie ma tu $expr?
> myślę, że w związku z powyższym tego już nie muszę wyjaśniać...
A jak by tak zmienić na
my $expr = "$host $re_oper /$opt{g}/";
?
--
grizzley
Re: Walidacja wyrażenia regularnego - operatory =~ i !~ jako zmienna
Author: ..:: sjf ::..
Date: Wed, 13 Jan 2010 20:39
Date: Wed, 13 Jan 2010 20:39
19 lines
1717 bytes
1717 bytes
W dniu 2010-01-13 15:17, Maciej Misiak pisze:
> ..:: sjf ::.. pisze:
>> W dniu 2010-01-06 20:42, Szymon Sokół pisze:
>>> On Wed, 06 Jan 2010 20:21:04 +0100, ..:: sjf ::.. wrote:
>>>
>>>> if ($opt{g}) {
>>>> my $expr = "$host $re_oper $opt{g}";
>>> ...i jaką w rezultacie ma tu $expr?
>> myślę, że w związku z powyższym tego już nie muszę wyjaśniać...
>
> A jak by tak zmienić na
> my $expr = "$host $re_oper /$opt{g}/";
> ?
Nic z tego - tak też próbowałem.
--
Szczepan J. Fijał :: sjf @ 50°07'N 18°58'E
xmpp:sjf@jabster.pl | tlen:sjf | gg:2604451 | skype:s.fijal?call
"Linux is like Wigwam. No gates, no windows... Apache inside ;-)"
Re: Walidacja wyrażenia regularnego - operatory =~ i !~ jako zmienna
Author: Maciej Misiak
Date: Sat, 16 Jan 2010 23:27
Date: Sat, 16 Jan 2010 23:27
27 lines
1891 bytes
1891 bytes
..:: sjf ::.. pisze:
> W dniu 2010-01-13 15:17, Maciej Misiak pisze:
>> ..:: sjf ::.. pisze:
>>> W dniu 2010-01-06 20:42, Szymon Sokół pisze:
>>>> On Wed, 06 Jan 2010 20:21:04 +0100, ..:: sjf ::.. wrote:
>>>>
>>>>> if ($opt{g}) {
>>>>> my $expr = "$host $re_oper $opt{g}";
>>>> ...i jaką w rezultacie ma tu $expr?
>>> myślę, że w związku z powyższym tego już nie muszę wyjaśniać...
>>
>> A jak by tak zmienić na
>> my $expr = "$host $re_oper /$opt{g}/";
>> ?
> Nic z tego - tak też próbowałem.
Hmm, mi działa. Wypisuje dokładnie to, co opisałeś, czyli
kt_e111
kt_e112
kt_e113
w pierwszym przypadku i wszystkie niepasujące do !~/ww_/ w drugim.
--
grizzley
PS. sorry za tak długie nieodpisywanie, jeszcze po Nowym Roku problemy z
nadążeniem za otaczającym światem...
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads