Jak porównać dwa ciągi w Perlu?
Uczę się Perla, miałem to podstawowe pytanie, sprawdziłem je tutaj w StackOverflow i nie znalazłem dobrej odpowiedzi, więc pomyślałem, że zapytam.
Jak porównać dwa ciągi w Perlu?
Uczę się Perla, miałem to podstawowe pytanie, sprawdziłem je tutaj w StackOverflow i nie znalazłem dobrej odpowiedzi, więc pomyślałem, że zapytam.
Odpowiedzi:
Zobacz perldoc perlop . Zastosowanie lt
, gt
, eq
, ne
, i cmp
odpowiednio dla porównań łańcuchowych:
eq
Funkcja binarna zwraca prawdę, jeśli lewy argument jest ciągiem równy prawemu.Dwójkowy
ne
Funkcja zwraca prawdę, jeśli lewy argument jest ciągiem różnym od prawego.Binarny
cmp
zwraca -1, 0 lub 1 w zależności od tego, czy lewy argument jest ciągiem mniejszy niż, równy lub większy niż prawy argument.Binary
~~
wykonuje smartmatch między swoimi argumentami. ...
lt
,le
,ge
,gt
Icmp
użyć sortowania (sortowanie) Order określonej przez bieżące locale jeśli locale użycie starszego typu (nieuse locale ':not_characters'
) jest w istocie. Zobacz perllocale . Nie mieszaj ich z Unicode, tylko ze starszymi kodowaniami binarnymi. Standardowe moduły Unicode :: Collate i Unicode :: Collate :: Locale oferują znacznie bardziej zaawansowane rozwiązania problemów z sortowaniem.
index
aby sprawdzić, czy ciąg jest podłańcuchem innego.
!=
i ne
nie są takie same, ponieważ !=
i ne
są zdefiniowane jako różne. Jak trudne to jest ?! Będąc liczbowym operatorem porównania, !=
konwertuje oba operandy na liczby perl -E 'say "equal" if not "a" != "b"'
.
cmp
Porównać
'a' cmp 'b' # -1
'b' cmp 'a' # 1
'a' cmp 'a' # 0
eq
Równy
'a' eq 'b' # 0
'b' eq 'a' # 0
'a' eq 'a' # 1
ne
Nie równe
'a' ne 'b' # 1
'b' ne 'a' # 1
'a' ne 'a' # 0
lt
Mniej niż
'a' lt 'b' # 1
'b' lt 'a' # 0
'a' lt 'a' # 0
le
Mniejszy lub równy
'a' le 'b' # 1
'b' le 'a' # 0
'a' le 'a' # 1
gt
Lepszy niż
'a' gt 'b' # 0
'b' gt 'a' # 1
'a' gt 'a' # 0
ge
Większe bądź równe
'a' ge 'b' # 0
'b' ge 'a' # 1
'a' ge 'a' # 1
Zobacz, perldoc perlop
aby uzyskać więcej informacji.
(Upraszczam to trochę, ponieważ wszystkie cmp
zwracają wartość, która jest zarówno pustym ciągiem, jak i wartością numeryczną zero zamiast 0
, oraz wartością, która jest zarówno ciągiem, jak '1'
i wartością liczbową 1
. Są to te same wartości, które będziesz zawsze otrzymuj z operatorów logicznych w Perlu. Zwracane wartości powinny być używane tylko dla operacji logicznych lub numerycznych, w takim przypadku różnica nie ma znaczenia).
eq
, gt
, lt
etc nie są poprawne ... Wracają prawdziwe lub fałszywe. cmp
Zwraca tylko określone wartości liczbowe.
leg
zamiast cmp
nich jest używany do porównań ogólnych.
Oprócz obszernej listy operatorów porównania ciągów przez Sinana Ünür, Perl 5.10 dodaje operator inteligentnego dopasowania.
Operator inteligentnego dopasowania porównuje dwa elementy na podstawie ich typu. Zobacz poniższy wykres dla zachowania 5.10 (uważam, że to zachowanie zmienia się nieznacznie w 5.10.1):
perldoc perlsyn
„Inteligentne dopasowanie szczegółów” :Zachowanie inteligentnego dopasowania zależy od typu rzeczy, które są jego argumentami. Jest zawsze przemienny, tj.
$a ~~ $b
Zachowuje się tak samo jak$b ~~ $a
. Zachowanie określa następująca tabela: pierwszy wiersz, który ma zastosowanie, w dowolnej kolejności, określa zachowanie dopasowania.
$ a $ b Rodzaj dopasowania Domniemany kod dopasowania ====== ===== ===================== ============= (przeciążenie przebija wszystko) Kod [+] Kod [+] równość referencyjna $ a == $ b Dowolny kod [+] skalarna prawda podrzędna $ b -> ($ a) Hash Hash Hash klucze identyczne [klucze sortowania% $ a] ~~ [klucze sortowania% $ b] Hash Array istnienie wycinka skrótu grep {istnieje $ a -> {$ _}} @ $ b Hash Regex hash key grep grep / $ b /, klucze% $ a Hash Istnieje każdy wpis z hashem $ a -> {$ b} Tablice Tablice Tablice są identyczne [*] Tablica Regex tablica grep grep / $ b /, @ $ a Tablica Num Tablica zawiera liczbę grep $ _ == $ b, @ $ a Tablica Dowolna tablica zawiera ciąg grep $ _ eq $ b, @ $ a Dowolne undef undefined! Define $ a Dowolny wzorzec Regex pasuje do $ a = ~ / $ b / Code () Wyniki Code () są równe $ a -> () eq $ b -> () Dowolne proste zamknięcie Code () $ b -> () # ignorujące $ a Num numish [!] Równość numeryczna $ a == $ b Dowolna równość łańcucha Str $ a eq $ b Dowolna równość liczbowa Num $ a == $ b Dowolna Dowolna równość łańcuchowa $ a eq $ b + - musi to być odwołanie do kodu, którego prototyp (jeśli istnieje) nie jest "" (subskrypcje z prototypem „” są obsługiwane przez pozycję „Kod ()” na dole) * - czyli każdy element pasuje do elementu o tym samym indeksie w drugim szyk. Jeśli zostanie znalezione odwołanie cykliczne, wracamy do referencji równość. ! - liczba rzeczywista lub ciąg, który wygląda jak liczbaOczywiście „pasujący kod” nie reprezentuje prawdziwego pasującego kodu: służy tylko do wyjaśnienia zamierzonego znaczenia. W przeciwieństwie do grepa, inteligentny operator dopasuje zwarcie, kiedy tylko będzie to możliwe.
Dopasowywanie niestandardowe przez przeciążanie Możesz zmienić sposób dopasowywania obiektu przez przeciążenie
~~
operatora. To przebija zwykłą semantykę inteligentnego dopasowania. Zobaczoverload
.
print "Matched!\n" if ($str1 eq $str2)
Perl ma oddzielne operatory porównania ciągów i liczb, które pomagają w luźnym pisaniu w języku. Powinieneś przeczytać perlop dla wszystkich różnych operatorów.
Oczywistym podtekstem tego pytania jest:
dlaczego nie możesz po prostu użyć
==
do sprawdzenia, czy dwa ciągi są takie same?
Perl nie ma odrębnych typów danych dla tekstu i liczb. Oba są reprezentowane przez typ „skalarny” . Innymi słowy, łańcuchy są liczbami, jeśli używasz ich jako takich .
if ( 4 == "4" ) { print "true"; } else { print "false"; }
true
if ( "4" == "4.0" ) { print "true"; } else { print "false"; }
true
print "3"+4
7
Ponieważ tekst i liczby nie są rozróżniane na podstawie języka, nie możemy po prostu przeciążać ==
operatora, aby zrobił właściwą rzecz w obu przypadkach. Dlatego Perl umożliwia eq
porównywanie wartości jako tekstu:
if ( "4" eq "4.0" ) { print "true"; } else { print "false"; }
false
if ( "4.0" eq "4.0" ) { print "true"; } else { print "false"; }
true
W skrócie:
==
lub !=
, aby porównać dwa operandy jako liczbyeq
lub ne
, aby porównać dwa operandy jako tekstIstnieje wiele innych funkcji i operatorów, których można użyć do porównania wartości skalarnych, ale znajomość różnicy między tymi dwoma formami jest ważnym pierwszym krokiem.
A jeśli chcesz wyodrębnić różnice między dwoma ciągami, możesz użyć String :: Diff .