Κανονικές εκφράσεις και αντιστοίχιση μοτίβων

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 σε χαρακτήρες. Η (καταργημένη) pragma use bytes μεταβαίνει σε byte offsets· νέος κώδικας δεν πρέπει να βασίζεται σε αυτό.

  • Αποτυχημένη αντιστοίχιση /g επαναφέρει τη θέση σε undef - η επόμενη /g ξεκινάει ξανά στο offset 0. Προσθέστε τον τροποποιητή /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 δεν εμπλέκεται, αλλά συχνά πιο καθαρή επιλογή όταν οι οριοθέτες είναι απλοί

  • \G anchor

    • zero-width anchor that binds to the current pos; the main reason to touch pos in the first place

  • $_ - προεπιλεγμένος στόχος της σκέτης pos