Τελεστές σύγκρισης συμβολοσειρών#

Τα ισοδύναμα σε γεύση συμβολοσειράς της οικογένειας αριθμητικής σύγκρισης. Ίδια μορφή, ίδια γραμμή προτεραιότητας, αλλά λειτουργία λεξικογραφικά (σειρά σημείων κώδικα Unicode από προεπιλογή) αντί αριθμητικά.

Τελεστής

Ερώτηση

Επιστρέφει

lt

μικρότερο από

αληθές / ψευδές

le

μικρότερο ή ίσο

αληθές / ψευδές

eq

ίσο

αληθές / ψευδές

ge

μεγαλύτερο ή ίσο

αληθές / ψευδές

gt

μεγαλύτερο από

αληθές / ψευδές

ne

άνισο

αληθές / ψευδές

cmp

τριμερής (sort)

-1, 0 ή +1

Οι δύο τελεστέοι εξαναγκάζονται σε συμβολοσειρές πριν τη σύγκριση.

$name eq "John"               # exact string match
$kind ne "guest"              # negated match
$word lt "m"                  # alphabetically before "m"
$a    cmp  $b                 # sort comparator

Λεξικογραφική σειρά#

Οι συμβολοσειρές συγκρίνονται χαρακτήρα-χαρακτήρα, σημείο κώδικα-σημείο κώδικα. Ο πρώτος διαφορετικός χαρακτήρας αποφασίζει· αν μια συμβολοσειρά είναι πρόθεμα της άλλης, η μικρότερη κερδίζει.

"abc" lt "abd"        # TRUE  -- 'c' < 'd' at position 2
"abc" lt "abcd"       # TRUE  -- prefix loses
"ABC" lt "abc"        # TRUE  -- ASCII: uppercase < lowercase
"10"  lt "9"          # TRUE  -- '1' < '9' at position 0 (lex, not numeric!)

Το τελευταίο παράδειγμα είναι ο κανονικός λόγος ύπαρξης των eq/lt/gt: όταν θέλετε συμβολοσειρές ψηφίων ταξινομημένες αριθμητικά, πρέπει να χρησιμοποιήσετε <=> ή να κάνετε προ-εξαναγκασμό.

Unicode#

Η σειρά σημείων κώδικα δεν είναι ίδια με τη «αλφαβητική» σειρά που λαμβάνει υπόψη τοπικές ρυθμίσεις:

  • Η "ä" gt "z" είναι TRUE σε σειρά σημείων κώδικα επειδή το U+00E4 βρίσκεται πέρα από το U+007A.

  • Σε σειρά DIN 5007-1 («λεξικό»), η "ä" πρέπει να ταξινομείται μαζί με "a" - πολύ πριν τη "z".

Για σωστή συνταξιοθεσία τοπικών ρυθμίσεων, χρησιμοποιήστε Unicode::Collate από perlfunc ή use locale με κατάλληλες τοπικές ρυθμίσεις. Οι σκέτοι lt/gt/cmp σας δίνουν διατεταγμένη, σταθερή, ανεξάρτητη γλώσσας σύγκριση - που είναι ακριβώς το σωστό για κλειδιά sort, κατακερματισμό hash, ντετερμινιστική έξοδο ελέγχων κ.ο.κ. Είναι το λάθος πράγμα για αλφαβητικές καταχωρήσεις προοριζόμενες για ανθρώπους σε οποιαδήποτε μη αγγλική γλώσσα.

cmp για ταξινόμηση#

Ο cmp είναι ο spaceship σύγκρισης συμβολοσειρών. Επιστρέφει -1, 0 ή +1 και αλυσιδώνεται με τον ίδιο τρόπο που αλυσιδώνεται ο <=>:

my @sorted = sort { $a cmp $b } @names;        # ascending lex order
my @cased  = sort {
    lc($a) cmp lc($b) || $a cmp $b             # case-insensitive,
                                               # ties broken by case
} @names;

Ανάμιξη γεύσεων: ένα αναλυμένο σφάλμα#

Το ιδίωμα ταξινόμησης σύνθετου κλειδιού από numeric comparison έδειξε αλυσίδωση || των <=> και cmp. Το σφάλμα που πρέπει να αποφύγετε είναι η χρήση του λάθος τελεστή για τον τύπο του κλειδιού:

# version strings like "1.10", "1.2", "1.20", ...
sort @versions                             # ASCII order:  "1.10","1.2","1.20"
sort { $a <=> $b } @versions               # numeric mash: works only by accident
                                           # (everything past first dot ignored)
sort { sortkey($a) <=> sortkey($b) } @versions   # parse first, then compare

Η σωστή απάντηση για συμβολοσειρές εκδόσεων είναι ένας αναλυτής όπως ο Sort::Versions ή χειροκίνητη τμηματοποίηση (\d+)· ούτε ο cmp ούτε ο <=> το κάνει σωστά μόνος του.

Προτεραιότητα#

Η σύγκριση συμβολοσειρών μοιράζεται τη γραμμή 11 του πίνακα precedence με την αριθμητική σύγκριση. Είναι μη προσεταιριστικοί - η προειδοποίηση αλυσίδωσης από numeric comparison ισχύει και εδώ:

"a" lt "b" lt "c"     # parses as ("a" lt "b") lt "c"
                      #         = 1            lt "c"
                      #         = TRUE  (because "1" < "c" lexically)
                      # - accidentally right for the wrong reason.

Γράψτε τη σύζευξη ρητά με &&.

Δείτε επίσης#

  • Numeric comparison - η παράλληλη οικογένεια.

  • sort, reverse, lc, uc, fc

    • perlfunc tools that pair with string comparison.

  • Unicode in Perl - η διάκριση τοπικών ρυθμίσεων / σειράς σημείων κώδικα σε βάθος.