🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: pl.comp.lang.perl
7 messages
7 total messages Started by Maciej Pilichowski Thu, 30 Apr 2009 14:35
regexp -- jak wymusic minimalne dopasowanie? (nie non-greedy)
#51348
Author: Maciej Pilichowski
Date: Thu, 30 Apr 2009 14:35
21 lines
1567 bytes
Hej,

  Najpierw troche terminologii zanim ktos mi zmyje glowe, ze nie chcialo mi 
sie google'ac. Dopasowania w perlu sa greedy i latwo je przestawic na non-
greedy. Masa ludzi zamiennie uzywa okreslenia, piszac iz non-greedy jest 
minimalnym dopasowaniem. Tak nie jest.

  Stad pytanie, jak w perlu zmusic regexpy, aby sie potrudzily i znalazly 
minimalne dopasowanie. Minimalne dopasowanie oznacza, ze dopasowanie 
dopasuje najmniejsza mozliwa liczbe znakow.

Jesli ktos nie wierzy, ze non-greedy tego nie robi:

my $s = "123X4567X890";
$s =~ s/X.*?$//;
print $s;

w wyniku dostaniemy 123, a nie 123X4567, a to drugie dopasowanie to wlasnie 
dopasowanie najmniejszej liczby znakow.

milego dnia zycze, hej
Re: regexp -- jak wymusic minimalne dopasowanie? (nie non-greedy)
#51349
Author: Maciej Misiak
Date: Thu, 30 Apr 2009 17:13
26 lines
2026 bytes
Maciej Pilichowski pisze:

> Jesli ktos nie wierzy, ze non-greedy tego nie robi:
> 
> my $s = "123X4567X890";
> $s =~ s/X.*?$//;
> print $s;
> 
> w wyniku dostaniemy 123, a nie 123X4567, a to drugie dopasowanie to wlasnie 
> dopasowanie najmniejszej liczby znakow.

Problem zdecydowanie sie; zmienia w momencie zastosowania kotwicy kon'ca 
tekstu. Przeanalizuj przyk?ady bez zakotwiczenia, a okaz.e sie;, z.e 
non-greedy dzia?a tak, jak ludzie opisuja;. Nawet kotwica pocza;tku tekstu 
nie narobi?aby takiego zamieszania :)
Nie do kon'ca jestem pewien tego, co teraz napisze;, ale powyz.szy regexp 
dzia?a tak, z.e najpierw jest czytany przez silnik regexpowy od pocza;tku, 
wyszukiwane jest pierwsze moz.liwe dopasowanie X albo X.*?, a naste;pnie 
widza;c kotwice; silnik zaczyna szukanie od kon'ca, a poniewaz. .*? pasuje 
do wszystkiego, co pomie;dzy, to dopasowuje sie; X4567X890.
Z.eby to zadzia?a?o jak chcesz, musia?bys' zmienic' podejs'cie do regexpa, 
czyli zastosowac' na przyk?ad cos' takiego
$s =~ s/(.*)X.*?$/$1/

-- 
grizzley
Re: regexp -- jak wymusic minimalne dopasowanie? (nie non-greedy)
#51350
Author: Maciej Pilichowski
Date: Fri, 01 May 2009 07:04
36 lines
1942 bytes
Maciej Misiak wrote:

> Problem zdecydowanie sie; zmienia w momencie zastosowania kotwicy kon'ca
> tekstu.

Nie, to chodzi o charakter regexpa, ktory dziala do przodu, a nie globalnie.

> Przeanalizuj przyk?ady bez zakotwiczenia, a okaz.e sie;, z.e
> non-greedy dzia?a tak, jak ludzie opisuja;.

Nie dziala:
A.*?B

dziala non-greedy, ale nie dopasowuje najkrotszego tekstu. To sa dwa rozne 
pojecia.

> Nawet kotwica pocza;tku tekstu
> nie narobi?aby takiego zamieszania :)

Bo nie ma nic przed nia, ale juz dla poczatku wiersza nie bedzie to prawda, 
(nawet nie sprawdzam) dla tekstu wielowierszowego
s/^.*?B/m

nie dopasuje najkrotszego ciagu, tylko pierwsze napotkane w trybie non-
greedy.

> Z.eby to zadzia?a?o jak chcesz, musia?bys' zmienic' podejs'cie do regexpa,
> czyli zastosowac' na przyk?ad cos' takiego
> $s =~ s/(.*)X.*?$/$1/

Niezly hack. Dzieki. 

Jesli ktos zna bardziej ogolne rozwiazanie (znak modyfikujacy tryb pracy) to 
nadal prosze o pomoc.

milego dnia, hej
Re: regexp -- jak wymusic minimalne dopasowanie? (nie non-greedy)
#51352
Author: teodozjan
Date: Fri, 01 May 2009 08:32
12 lines
1823 bytes
On 1 Maj, 09:04, Maciej Pilichowski <ba...@SKASUJTOpoczta.FM> wrote:

> Jesli ktos zna bardziej ogolne rozwiazanie (znak modyfikujacy tryb pracy) to
> nadal prosze o pomoc.
>
> milego dnia, hej

Nie mogę wyobrazić sobie ogólnego rozwiązania. Taki regexp musiałby
przeprowadzić kilka dopasowań i wybrać najkrótsze. Kolega przedstawił
Ci rozwiązanie dowolna ilość praktycznie dowolnych znaków w wersji
chciwej, X oraz dowolna ilość znaków w wersji niechciwej, dla mnie
żaden hack.
Re: regexp -- jak wymusic minimalne dopasowanie? (nie non-greedy)
#51353
Author: Maciej Misiak
Date: Fri, 01 May 2009 11:26
24 lines
1537 bytes
Maciej Pilichowski pisze:

> dziala non-greedy, ale nie dopasowuje najkrotszego tekstu. To sa dwa rozne 
> pojecia.

Dobra, teraz zrozumialem pytanie :)
Jedyne, co mi przychodzi do głowy, to pętla, w której stopniowo 
zwiększamy ilość znaków, które chcemy znaleźć:

d:\>perl -le "$_='1X23X456X7890XaaaXbXv';for$i(1..5){print$& if /X.{$i}X/}"
XbX
X23X
X456X
X7890X
XaaaXbX

d:\>perl -le "$_='1X23X456X7890XaaaXbXv';for$i(1..5){print($&),last if 
/X.{$i}X/}"
XbX

-- 
grizzley

PS. sorki za krzaczki polskoogonkowe w poprzednim poście
Re: regexp -- jak wymusic minimalne dopasowanie? (nie non-greedy)
#51354
Author: Maciej Pilichowski
Date: Fri, 01 May 2009 18:28
13 lines
1297 bytes
Maciej Misiak wrote:

> Maciej Pilichowski pisze:
> 
>> dziala non-greedy, ale nie dopasowuje najkrotszego tekstu. To sa dwa
>> rozne pojecia.
> 
> Dobra, teraz zrozumialem pytanie :)

Ok :-) Ale to poprzednie rozwiazanie jest lepsze, bo opiera sie tylko na 
regexpie, bez wlaczanego kodu.

milego dnia, hej
Re: regexp -- jak wymusic minimalne dopasowanie? (nie non-greedy)
#51351
Author: Maciej Pilichowski
Date: Fri, 01 May 2009 18:30
29 lines
1735 bytes
teodozjan wrote:

> Nie mogę wyobrazić sobie ogólnego rozwiązania. Taki regexp musiałby
> przeprowadzić kilka dopasowań i wybrać najkrótsze. 

No zgadza sie :-)

> Kolega przedstawił
> Ci rozwiązanie dowolna ilość praktycznie dowolnych znaków w wersji
> chciwej, X oraz dowolna ilość znaków w wersji niechciwej, dla mnie
> żaden hack.

Nie uzywam slowa hack pejoratywnie -- chodzilo mi o to, ze jest to 
rozwiazanie nie wprost.

np.

a[^b]*b

daje to samo co 

a.*?b

ale to pierwsze to wlasnie hack, bo intencja jest ukryta.

Za rozwiazanie oczywiscie jestem wdzieczny, bo robi dokladnie to co 
chcialem.

milego dnia, hej
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