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

m//#

Αναζητά σε μια συμβολοσειρά ένα μοτίβο και αναφέρει αν - και τι - ταίριαξε.

Το m// είναι ο τελεστής αντιστοίχισης. Μεταγλωττίζει το PATTERN ως κανονική έκφραση (δείτε τον οδηγό regex), το εκτελεί έναντι μιας συμβολοσειράς-στόχου, και επιστρέφει μια τιμή με σχήμα που καθορίζεται από το περιβάλλον κλήσης και τους τροποποιητές που εφαρμόζετε. Στόχος είναι ό,τι βρίσκεται αριστερά του =~ ή του !~· χωρίς τελεστή σύνδεσης, ο στόχος είναι η $_. Το αρχικό m είναι προαιρετικό όταν ο οριοθέτης είναι /, οπότε τα /PATTERN/ και m/PATTERN/ σημαίνουν το ίδιο πράγμα.

Σύνοψη#

$str =~ m/PATTERN/flags
$str =~ /PATTERN/flags
m/PATTERN/flags              # target is $_
/PATTERN/flags               # target is $_
$str =~ m{PATTERN}flags      # any paired non-word delimiters

Τι επιστρέφεται#

Το περιβάλλον αποφασίζει το σχήμα της τιμής επιστροφής.

  • Βαθμωτό περιβάλλον, χωρίς /g: 1 σε αντιστοιχία, η κενή συμβολοσειρά σε μη αντιστοιχία. Και οι δύο χρησιμοποιούνται ως λογικές τιμές· η κενή συμβολοσειρά είναι ψευδής με διπλή τιμή που ισούται επίσης αριθμητικά με 0.

  • Περιβάλλον λίστας, χωρίς /g: η λίστα τιμών σύλληψης ($1, $2, $3, …) σε επιτυχημένη αντιστοιχία· αν το μοτίβο δεν έχει ομάδες σύλληψης, η μονοσύνολη (1)· σε αποτυχία, η κενή λίστα. Έτσι λειτουργεί το if (my ($x, $y) = $s =~ /(\w+)=(\w+)/).

  • Βαθμωτό περιβάλλον, /g: κάθε κλήση προχωρά μέσα στη συμβολοσειρά, επιστρέφοντας αληθές για την επόμενη αντιστοιχία και ψευδές μόλις δεν υπάρχουν άλλες. Η pos στον στόχο παρακολουθεί από πού θα ξεκινήσει η επόμενη απόπειρα.

  • Περιβάλλον λίστας, /g: όλες οι αντιστοιχίες με μία κίνηση. Με ομάδες σύλληψης, η επίπεδη λίστα όλων των συλλήψεων από κάθε αντιστοιχία. Χωρίς συλλήψεις, η λίστα κάθε πλήρους αντιστοιχίας.

Οι επιτυχημένες αντιστοιχίες γεμίζουν επίσης τις ειδικές μεταβλητές regex ($1 έως $9, $&, $`, $', $+, %+, %-) για την περικλείουσα δυναμική εμβέλεια. Μια αποτυχημένη αντιστοιχία τις αφήνει να κρατούν τις προηγούμενες τιμές τους - ελέγχετε πάντα την ίδια την αντιστοιχία, ποτέ μια μεταβλητή σύλληψης, για να αποφασίσετε αν συνέβη αντιστοιχία.

Καθολική κατάσταση που επηρεάζει#

  • $_ - ο προεπιλεγμένος στόχος όταν δεν δίνεται σύνδεση =~.

  • $1, $2, … - αριθμημένες συλλήψεις, τίθενται σε επιτυχία, αμετάβλητες σε αποτυχία.

  • $&, $`, $' - αντιστοιχία, προ-αντιστοιχία, μετα-αντιστοιχία.

  • $+ - η σύλληψη με τον μεγαλύτερο αριθμό που πράγματι ταίριαξε (χρήσιμη με εναλλαγές).

  • %+, %- - hashes ονομαστικών συλλήψεων.

  • ${^LAST_SUCCESSFUL_PATTERN} - το τελευταίο μοτίβο που ταίριαξε στην τρέχουσα δυναμική εμβέλεια· επίσης το μοτίβο που η κενή μορφή m// επαναχρησιμοποιεί (δείτε Οριακές περιπτώσεις).

  • pos στη συμβολοσειρά-στόχο - διαβάζεται και ενημερώνεται από αντιστοίχιση /g· επανέρχεται σε αποτυχία εκτός αν τεθεί επίσης το /c.

  • Πηγές κανόνων locale / Unicode όταν ισχύουν οι /l, /u ή /d.

Οριοθέτες#

Με m, οποιοδήποτε ζεύγος μη-λευκών χαρακτήρων λειτουργεί ως οριοθέτης, και τα ζεύγη αγκυλών εμφωλεύονται:

m/pattern/
m{pattern}
m[pattern]
m(pattern)
m<pattern>
m!pattern!
m#pattern#
m,pattern,

Επιλέγοντας οριοθέτη που δεν εμφανίζεται στο μοτίβο αποφεύγετε τη συσσώρευση backslash - γνωστή ως LTS, leaning toothpick syndrome (σύνδρομο γερτής οδοντογλυφίδας). Ένα μοτίβο αντιστοίχισης διαδρομών διαβάζεται καθαρά με m{…} ή m!…! και άσχημα με m/…/.

Δύο επιλογές οριοθέτη αλλάζουν τη σημασιολογία:

  • ' (μονό εισαγωγικό) - καμία παρεμβολή μεταβλητών μέσα στο PATTERN. Το m'$foo' ταιριάζει τους κυριολεκτικούς τέσσερις χαρακτήρες.

  • ? - το m?PATTERN? ταιριάζει μόνο μία φορά μεταξύ κλήσεων στην reset. Το αρχικό m είναι υποχρεωτικό· από την Perl 5.22 και μετά, η γυμνή μορφή ?…? είναι συντακτικό σφάλμα.

Όταν ο οριοθέτης είναι χαρακτήρας λέξης (γράμμα ή ψηφίο), απαιτείται κενό μετά το m: το m q foo q είναι νόμιμο, το mqfooq δεν είναι.

Τροποποιητές#

Τροποποιητές μεταγλώττισης μοτίβου (γίνονται επίσης δεκτοί από qr, s και split):

  • m - πολυγραμμικός: τα ^ και $ ταιριάζουν σε κάθε ενσωματωμένο newline, όχι μόνο στα άκρα της συμβολοσειράς.

  • s - μονογραμμικός: το . ταιριάζει κάθε χαρακτήρα συμπεριλαμβανομένου του newline.

  • i - αντιστοίχιση χωρίς διάκριση πεζών-κεφαλαίων.

  • x - αγνοεί λευκούς χαρακτήρες και σχόλια # στο μοτίβο· το xx το επεκτείνει και στις κλάσεις χαρακτήρων.

  • p - διατηρεί αντίγραφα της αντιστοιχισμένης συμβολοσειράς. Από την 5.20 είναι no-op - οι ${^PREMATCH}, ${^MATCH}, ${^POSTMATCH} είναι πάντα διαθέσιμες μετά από επιτυχημένη αντιστοιχία.

  • a, u, l, d - κανόνες συνόλου χαρακτήρων για τα \d, \s, \w, και τις κλάσεις POSIX. Το /a τους περιορίζει σε ASCII· το /aa επιπρόσθετα απαγορεύει αντιστοίχιση ASCII/μη-ASCII υπό /i.

  • n - μη συλλαμβάνων: το (…) συμπεριφέρεται σαν (?:…) και δεν γεμίζει τις $1, $2, ….

  • o - μεταγλωττίζει το μοτίβο ακριβώς μία φορά ακόμη και αν αλλάξουν οι παρεμβαλλόμενες μεταβλητές. Σχεδόν πάντα λάθος εργαλείο· χρησιμοποιήστε αντ” αυτού qr για να φτιάξετε ένα επαναχρησιμοποιήσιμο μεταγλωττισμένο μοτίβο.

Τροποποιητές διαδικασίας αντιστοίχισης (αποκλειστικοί στα m// και s///):

  • g - καθολική αντιστοίχιση. Σε βαθμωτό περιβάλλον η συμπεριφορά είναι επαναληπτική (προχωρά την pos σε κάθε κλήση)· σε περιβάλλον λίστας η συμπεριφορά επιστρέφει όλες τις αντιστοιχίες μαζί.

  • c - έχει νόημα μόνο με /g. Μια αποτυχημένη αντιστοιχία /g διατηρεί την pos εκεί που ήταν αντί να την επαναφέρει στην αρχή· απαραίτητο για σαρωτές τύπου lex χτισμένους γύρω από το \G.

Παραδείγματα#

Έλεγχος αν μια συμβολοσειρά περιέχει ένα μοτίβο:

if ($line =~ /error/i) {
    warn "matched: $line";
}

Δέσμευση σύλληψης σε μία κίνηση:

if (my ($key, $val) = $line =~ /^(\w+)\s*=\s*(.*)$/) {
    $config{$key} = $val;
}

Εξαγωγή κάθε αριθμού από μια συμβολοσειρά με /g σε περιβάλλον λίστας:

my @nums = "x=1 y=22 z=333" =~ /(\d+)/g;
# @nums = (1, 22, 333)

Επανάληψη μία προς μία στις αντιστοιχίες με /g σε βαθμωτό περιβάλλον, χρησιμοποιώντας την pos για να δείτε πού βρίσκεται η μηχανή:

my $s = "foo 1 bar 22 baz 333";
while ($s =~ /(\d+)/g) {
    printf "matched %s at offset %d\n", $1, pos($s) - length($1);
}

Εκτεταμένη μορφή με τον τροποποιητή x και ονομαστικές συλλήψεις:

if ($ts =~ m{
        ^ (?<year>\d{4}) -
          (?<mon> \d{2}) -
          (?<day> \d{2}) $
    }x) {
    printf "year=%s mon=%s day=%s\n", $+{year}, $+{mon}, $+{day};
}

Αποφύγετε το LTS επιλέγοντας οριοθέτη που δεν εμφανίζεται στο μοτίβο:

next if $path =~ m{^/usr/local/};

Χρησιμοποιήστε το \G με m//gc για να διασχίζετε μια συμβολοσειρά token-προς-token χωρίς να χάνετε τη θέση σε αποτυχημένη διακλάδωση:

while (1) {
    if    ($s =~ /\G(\d+)/gc)    { push @tok, ['num',  $1] }
    elsif ($s =~ /\G(\w+)/gc)    { push @tok, ['word', $1] }
    elsif ($s =~ /\G(\s+)/gc)    { next                   }
    else                         { last                   }
}

Οριακές περιπτώσεις#

  • Κενό μοτίβο: τα // και m// επαναχρησιμοποιούν το τελευταίο μοτίβο που ταίριαξε επιτυχώς στην τρέχουσα δυναμική εμβέλεια. Αν δεν έχει ταιριάξει τίποτα ακόμη, ένα κενό μοτίβο ταιριάζει παντού. Η απευθείας διαβίβαση εισόδου χρήστη στο m/$pat/ όταν η $pat μπορεί να είναι κενή είναι αιχμηρό άκρο - τυλίξτε το σε μη συλλαμβάνουσα ομάδα: m/(?:$pat)/. Το τελευταίο επιτυχημένο μοτίβο είναι επίσης αναγνώσιμο ως ${^LAST_SUCCESSFUL_PATTERN}.

  • Αμφισημία defined-or: Η Perl αναλύει το $x // $y ως τον τελεστή defined-or, ποτέ ως δύο κενές αντιστοιχίες. Σε παθολογικές θέσεις (print $fh //) η Perl εξακολουθεί να υποθέτει defined-or· εξαναγκάστε αντιστοιχία γράφοντας ρητά m// ή χωρίζοντας με κενά τους οριοθέτες.

  • Αποτυχημένη αντιστοιχία αφήνει τις συλλήψεις παλιωμένες: η $1 μετά από μια αποτυχημένη /…/ εξακολουθεί να κρατά τη σύλληψη από την προηγούμενη επιτυχημένη αντιστοιχία - βάζετε πάντα φραγμό στη χρήση των συλλήψεων με βάση το αποτέλεσμα της αντιστοιχίας.

  • /o με μεταβαλλόμενες μεταβλητές: το m/$x/o κλειδώνει την πρώτη τιμή της $x στο μεταγλωττισμένο μοτίβο. Μεταγενέστερες αλλαγές στην $x αγνοούνται σιωπηλά. Καταφύγετε στην qr όταν θέλετε ρητή, επαναχρησιμοποιήσιμη μεταγλώττιση.

  • Παρεμβολή όταν ο οριοθέτης είναι ': το m'$var' είναι κυριολεκτική αντιστοίχιση δολαρίου-var. Αυτό σπάνια είναι αυτό που θέλετε, και το ίδιο αποτέλεσμα είναι διαθέσιμο με \Q…\E ή quotemeta σε οποιονδήποτε άλλο οριοθέτη.

  • /g συν τροποποίηση στόχου: η τροποποίηση του στόχου μεταξύ επαναλήψεων /g επαναφέρει την pos στην αρχή. Επαναλάβετε πάνω σε αντίγραφο αν χρειάζεται να μεταβάλλετε το πρωτότυπο καθώς προχωράτε.

  • \G εκτός /g: χωρίς /g, το \G αγκυρώνει στην pos που είχε ο στόχος τη στιγμή της κλήσης και ταιριάζει το πολύ μία φορά. Σε συμβολοσειρά στην οποία δεν έχει ποτέ εφαρμοστεί /g, το \G ισοδυναμεί με \A.

  • Εμβέλεια reset του m?…?: η reset καθαρίζει την κατάσταση m?? μόνο για το τρέχον πακέτο. Ένα m?? σε ένα πακέτο δεν επηρεάζεται από reset που κλήθηκε από άλλο.

  • Τελεστές σύγκρισης κοντά σε κενό regex: το $x //= 1 είναι πάντα η ανάθεση defined-or· αν θέλετε πραγματικά το κενό regex, γράψτε m// αντί για //.

Διαφορές από το upstream#

Πλήρως συμβατό με το upstream Perl 5.42.

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

  • qr - μεταγλωττίζει ένα μοτίβο μία φορά και το επαναχρησιμοποιεί· αποφεύγει το /o και διατηρεί το μοτίβο τιμή πρώτης τάξης

  • s - ίδια σύνταξη μοτίβου, αντικαθιστά ό,τι ταιριάζει

  • tr - μετάφραση χαρακτήρα-προς-χαρακτήρα· διαφορετικό εργαλείο με επιφανειακά παρόμοιο σχήμα

  • split - όταν θέλετε τα κομμάτια μεταξύ των αντιστοιχιών αντί για τις ίδιες τις αντιστοιχίες

  • pos - διαβάζει ή ορίζει τη θέση από την οποία συνεχίζει η αντιστοίχιση /g

  • Regular expressions guide

    • the regex language itself: assertions, character classes, backreferences, named captures