2011-08-06 16 views
8

O ile wiem, w perlu globalna flaga "/ g" oznacza, że ​​wyszukiwanie zastąpi/zwróci wszystkie dopasowania w ciągu znaków. Ale nie jestem w stanie zrozumieć sposób, w jaki reaguje na zmienne globalne, dopasowując, może ktoś wyjaśnić, dlaczego istnieje różnica między produkcją tych dwóch przykładowych programów:Pomóż zrozumieć flagę globalną w perlu

Wersja 1:

my $text = 'This is sample float value 3.2 '; 

getFloat(); 
getFloat(); 

sub getFloat(){ 
    if ($text =~ /([0-9]+?)(.?)([0-9]+?)/is){ 
     print "matched> $1$2$3 "; 
    } 
} 

wyjście: dopasowane> 3,2 dopasowane> 3,2

Wersja 2: (z globalnej flagi)

my $text = 'This is sample float value 3.2 '; 

getFloat(); 
getFloat(); 

sub getFloat(){ 
    if ($text =~ /([0-9]+?)(.?)([0-9]+?)/gis){ 
     print "matched> $1$2$3 "; 
    } 
} 

wyjściowa: dopasowane> 3,2

Jak widać z wyjść z globalnego flag dopasowanie występuje tylko raz. Czy ktoś może wyjaśnić to zachowanie.

+0

Powinieneś rzucić okiem na [perldoc perlretut] (http://perldoc.perl.org/perlretut.html#Using-regular-expressions- in-Perl) – TLP

+0

Czego się spodziewasz? Chcesz, żeby pasował, dopóki nie pasuje? Czy nie oznacza to, że warunek "jeśli" zawsze byłby fałszywy. W skrócie, 'if (/.../ g)' nie ma sensu. – ikegami

Odpowiedz

10

Przy pomocy modyfikatora g, ciąg zapamiętuje miejsce jego ostatniego dopasowania, więc możesz poprosić o dopasowanie z g w pętli while i znaleźć wszystkie dopasowania.

Bez numeru g rozpoczynasz od początku za każdym razem i zawsze znajdujesz pierwsze dopasowanie.

W twoim przypadku, z g, pasowałeś do 3.2 za pierwszym razem, ale za drugim razem, gdy próbowałeś się dopasować, nie było więcej dopasowań.

Bez g możesz zadzwonić pod numer getFloat(), a zawsze znajdziesz pierwszy mecz.

+0

Dzięki za odpowiedź na pytanie Ray –

8

W przypadku użycia w kontekście listy, /g powoduje, że =~ zwraca wszystkie dopasowania. W przypadku użycia w kontekście skalarnym, /g powoduje, że =~ zwraca jeden mecz za każdym razem, gdy jest używany, a następnie kończy się niepowodzeniem (zwraca undef), gdy nie ma więcej dopasowań, przed ponownym uruchomieniem na początku ciągu. (Możesz temu zapobiec za pomocą /gc.) Możesz także użyć funkcji pos($text), aby znaleźć lub ustawić pozycję, od której zaczniesz mecz.

Bez /g, =~ zawsze zwraca ten sam mecz za każdym razem. Jest to równoważne ustawieniu pos($text) na undef za każdym razem. (W kontekście listy, zamiast tego zwraca listę przechwyceń.)

Powiązane problemy