Κανονικές εκφράσεις και αντιστοίχιση μοτίβων
pos#
Αναφέρει ή ορίζει πού θα συνεχιστεί η επόμενη αντιστοίχιση regex /g σε μια συμβολοσειρά.
Η pos διαβάζει (ή, ως lvalue, γράφει) το offset που η μηχανή regex αποθηκεύει σε ένα βαθμωτό μετά από καθολική αντιστοίχιση (m//g, s///g). Το offset μετράει χαρακτήρες, όχι bytes, και είναι η θέση μετά την τελευταία επιτυχημένη αντιστοίχιση - το σημείο όπου η επόμενη επανάληψη /g θα ξεκινήσει τη σάρωση. Χωρίς όρισμα η pos λειτουργεί πάνω στην $_.
Σύνοψη#
pos SCALAR
pos $str = N
pos
Τι επιστρέφεται#
Ένα ακέραιο offset, ή undef όταν δεν είναι καταγεγραμμένη θέση. Το 0 είναι έγκυρο offset και σημαίνει «αρχή συμβολοσειράς»· δεν είναι το ίδιο με undef, που σημαίνει «καμία αντιστοίχιση /g δεν έχει τρέξει, ή η τελευταία απέτυχε και επανέφερε τη θέση.» Πάντα διακρίνετε τα δύο με defined:
if (defined pos $str) {
# a /g scan is in progress
}
Χρησιμοποιούμενη ως lvalue, η pos SCALAR επιστρέφει μια θέση όπου μπορείτε να αναθέσετε:
pos($str) = 5; # next /g match starts at char offset 5
Καθολική κατάσταση που επηρεάζει#
Η pos διαβάζει και γράφει τη θέση regex ανά-βαθμωτό που συνδέεται με τον τελεστέο της. Χωρίς όρισμα στοχεύει την $_. Το αποθηκευμένο offset είναι αυτό στο οποίο αγκυρώνεται η \G στην επόμενη αντιστοίχιση, οπότε κάθε κλήση στην pos ενδέχεται να αλλάξει το πού δένει η \G.
Παραδείγματα#
Διασχίστε κάθε λέξη σε μια συμβολοσειρά με /g σε βαθμωτό περιβάλλον, χρησιμοποιώντας την pos για να αναφέρετε την πρόοδο:
my $s = "one two three";
while ($s =~ /(\w+)/g) {
printf "%-5s ends at %d\n", $1, pos $s;
}
# one ends at 3
# two ends at 7
# three ends at 13
Παραλείψτε μπροστά πριν ξεκινήσετε τη σάρωση. Η πρώτη αντιστοίχιση αρχίζει στο offset 4, όχι 0:
my $s = "AAA BBB CCC";
pos($s) = 4;
$s =~ /(\w+)/g;
print $1, "\n"; # BBB
Αγκυρώστε μια επόμενη αντιστοίχιση στην προηγούμενη με την \G. Χωρίς την \G η μηχανή θα σαρώσει προς τα μπρος πέρα από οποιοδήποτε κενό· με αυτήν, η αντιστοίχιση πρέπει να ξεκινήσει ακριβώς εκεί όπου τελείωσε η τελευταία:
my $s = "12ab34cd";
while ($s =~ /\G(\d+)(\w+?)(?=\d|\z)/g) {
print "num=$1 tail=$2\n";
}
# num=12 tail=ab
# num=34 tail=cd
Επανεκκινήστε μια σάρωση καθαρίζοντας τη θέση:
pos($s) = undef; # next /g starts from offset 0 again
Οριακές περιπτώσεις#
Η σκέτη
posστοχεύει την$_. Ηposμέσα σεwhile (<>) { ... }συνεπώς αναφέρει τη θέση στην τρέχουσα γραμμή εισόδου.Χαρακτήρες, όχι bytes. Για συμβολοσειρά που περιέχει multi-byte χαρακτήρες, η
posεπιστρέφει το offset σε χαρακτήρες. Η (καταργημένη) pragmause bytesμεταβαίνει σε byte offsets· νέος κώδικας δεν πρέπει να βασίζεται σε αυτό.Αποτυχημένη αντιστοίχιση
/gεπαναφέρει τη θέση σεundef- η επόμενη/gξεκινάει ξανά στο offset0. Προσθέστε τον τροποποιητή/c(m//gc) για να διατηρήσετε τη θέση σε αποτυχία, που είναι το συνηθισμένο ιδίωμα όταν συνθέτετε πολλά εναλλακτικά μοτίβα αγκυρωμένα με\Gπάνω στην ίδια συμβολοσειρά.Οι αναγνώσεις κατά τη διάρκεια μιας αντιστοίχισης είναι παλιές. Η
posαντικατοπτρίζει το τέλος της προηγούμενης αντιστοίχισης. Εκφράσεις όπως(?{ pos() = 5 })ήs//pos() = 5/eεπηρεάζουν την επόμενη αντιστοίχιση, όχι αυτήν που τρέχει τώρα.Σημαία αντιστοίχισης μηδενικού μήκους. Ο ορισμός της
posεπίσης καθαρίζει την εσωτερική σημαία αντιστοιχήθηκε με μηδενικό μήκος, ώστε μια επόμενη αντιστοίχιση μηδενικού πλάτους στην ίδια θέση να επιτρέπεται ξανά. Δείτε το κεφάλαιο επίδοσης του οδηγού regex υπό την ενότητα τερματισμός αντιστοίχισης μηδενικού μήκους.Τελεστέος που δεν είναι lvalue. Η
posαπαιτεί πραγματική βαθμωτή μεταβλητή για τη μορφή lvalue· τοpos("literal") = 3είναι σφάλμα κατά τη μεταγλώττιση.Offset
0έναντιundef. Ηposμε τιμή0σημαίνει ότι η επόμενη/gξεκινάει από την αρχή· ηundefσημαίνει ότι δεν είναι ορισμένη θέση. Συμπεριφέρονται πανομοιότυπα για την πρώτη αντιστοίχιση αλλά διαφέρουν όταν ληφθεί υπόψη η κατάσταση της σημαίας αντιστοίχισης μηδενικού μήκους.
Διαφορές από το upstream#
Πλήρως συμβατό με το upstream Perl 5.42.
Δείτε επίσης#
m- ο τροποποιητής/gείναι αυτός που δημιουργεί και προωθεί τη θέση που διαβάζει ηpos· ο τροποποιητής/cσε αποτυχία τη διατηρείqr- προμεταγλωττίστε ένα μοτίβο μία φορά, και μετά επαναχρησιμοποιήστε το σε βρόχους/gαγκυρωμένους με\Gχωρίς εκ νέου ανάλυσηsplit- ο άλλος καθημερινός τρόπος να διασχίσετε μια συμβολοσειρά σε κομμάτια· καμίαposδεν εμπλέκεται, αλλά συχνά πιο καθαρή επιλογή όταν οι οριοθέτες είναι απλοί-
zero-width anchor that binds to the current
pos; the main reason to touchposin the first place
$_- προεπιλεγμένος στόχος της σκέτηςpos