Κανονικές εκφράσεις και αντιστοίχιση μοτίβων
s///#
Αναζητά σε μια συμβολοσειρά ένα μοτίβο και αντικαθιστά κάθε αντιστοιχία με ένα κείμενο αντικατάστασης.
Ο s/// είναι ο τελεστής αντικατάστασης της Perl. Εντοπίζει κείμενο που ταιριάζει με το PATTERN στη συμβολοσειρά-στόχο, αντικαθιστά κάθε αντιστοιχία με το REPLACEMENT, και εξ ορισμού επιστρέφει τον αριθμό των αντικαταστάσεων που έγιναν. Χωρίς ρητό στόχο (χωρίς =~ ή !~), λειτουργεί επί του $_. Ο στόχος πρέπει να είναι βαθμωτό lvalue - μεταβλητή, στοιχείο πίνακα ή hash, ή substr / ανάθεση που παράγει ένα - εκτός αν χρησιμοποιηθεί η σημαία /r, η οποία λειτουργεί σε οποιαδήποτε τιμή και επιστρέφει το τροποποιημένο αντίγραφο.
Σύνοψη#
s/PATTERN/REPLACEMENT/FLAGS
$str =~ s/PATTERN/REPLACEMENT/FLAGS
$str !~ s/PATTERN/REPLACEMENT/FLAGS
my $copy = $str =~ s/PATTERN/REPLACEMENT/r
Τι επιστρέφεται#
Εξ ορισμού, το πλήθος των αντικαταστάσεων που πραγματοποιήθηκαν ως ακέραιος: 0 όταν τίποτα δεν ταίριαξε (το οποίο είναι ψευδές σε λογικό περιβάλλον), θετικός ακέραιος σε επιτυχία. Το βαθμωτό-στόχος τροποποιείται επιτόπια.
Με τη σημαία /r, η σημασιολογία αντιστρέφεται: ο στόχος δεν τροποποιείται, και ο τελεστής επιστρέφει τη (πιθανώς αλλαγμένη) συμβολοσειρά. Αν τίποτα δεν ταίριαξε, το /r εξακολουθεί να επιστρέφει αντίγραφο του πρωτοτύπου. Το αποτέλεσμα του /r είναι πάντα απλή συμβολοσειρά, ακόμη και όταν η πηγή είναι tied μεταβλητή ή blessed αντικείμενο με υπερφόρτωση.
Το !~ αντιστρέφει τη λογική έννοια της τιμής επιστροφής: αποδίδει αληθές όταν δεν έγινε καμία αντικατάσταση, ψευδές όταν έγινε τουλάχιστον μία αντικατάσταση. Ο στόχος εξακολουθεί να τροποποιείται και στις δύο περιπτώσεις.
my $n = ($text =~ s/foo/bar/g); # count of replacements
my $out = $text =~ s/foo/bar/r; # copy-and-modify, $text untouched
Καθολική κατάσταση που επηρεάζει#
$_- ο προεπιλεγμένος στόχος όταν δεν δίνεται=~ή!~. Τοs/old/new/χωρίς σύνδεση διαβάζει και γράφει το$_.Τα
$&, [`$``](../perlvar), [`$”`](../perlvar), [`$1`](../perlvar) και τα όμοιά τους - ορίζονται από κάθε επιτυχημένη αντιστοιχία, ακριβώς όπως τα ορίζει η [`m//`](m). Μέσα στο `REPLACEMENT` αναφέρονται στην τρέχουσα αντιστοιχία, όχι σε προηγούμενη.pos- εκκαθαρίζεται στο βαθμωτό-στόχο από μια επιτυχημένη μη-/gαντικατάσταση· υπό το/gπροχωρά με κάθε αντιστοιχία και μπορεί να ελεγχθεί μεταξύ επαναλήψεων.Το τελευταίο επιτυχημένο μοτίβο - χρησιμοποιείται όταν το
PATTERNαξιολογείται στην κενή συμβολοσειρά (τοs//new/επαναχρησιμοποιεί την τελευταία επιτυχημένη regex από αυτή την εμβέλεια).Τα
$/,$\και οι διαχωριστές εξόδου δεν επηρεάζονται - τοs///παράγει συμβολοσειρά, δεν γράφει.
Σημαίες#
Το πλήρες σύνολο είναι msixpodualngcer. Οι σημαίες πλευράς αντιστοίχισης συμπεριφέρονται ακριβώς όπως στα m// και qr· δείτε το κεφάλαιο τροποποιητών του οδηγού regex για τις λεπτομέρειες πλευράς αντιστοίχισης. Σημαίες ειδικές για την αντικατάσταση:
e- αξιολογεί τοREPLACEMENTως μπλοκ κώδικα Perl. Η τιμή του μπλοκ είναι η συμβολοσειρά αντικατάστασης. Ισοδύναμο με την περιτύλιξή του σεdo { ... }και τη συμβολοσειροποίηση του αποτελέσματος.ee- αξιολογεί ως κώδικα, και έπειτα κάνειevalτην προκύπτουσα συμβολοσειρά ξανά. Ισοδύναμο μεeval(do { REPLACEMENT }). Επιπλέον τροποποιητέςeπροσθέτουν περισσότερα στρώματαeval.r- μη καταστροφικό: αφήνει τον στόχο αμετάβλητο και επιστρέφει το τροποποιημένο αντίγραφο (ή αμετάβλητο αντίγραφο σε περίπτωση μη αντιστοιχίας). Δεν μπορεί να συνδυαστεί με τον περιορισμό μη-βαθμωτού lvalue στόχου - οποιαδήποτε έκφραση είναι έγκυρος στόχος υπό το/r.g- καθολικό: αντικαθιστά κάθε μη επικαλυπτόμενη αντιστοιχία, όχι μόνο την πρώτη.c- γίνεται δεκτό για συντακτική συμμετρία με τηm//αλλά δεν έχει επίδραση στη συμπεριφορά τουs///· ενεργοποιεί προειδοποίηση υπό τοuse warnings.
Σημαίες πλευράς αντιστοίχισης σε μία γραμμή: m (πολυγραμμικά ^/$), s (το . αντιστοιχίζει νέα γραμμή), i (χωρίς διάκριση πεζών-κεφαλαίων), x / xx (εκτεταμένα κενά, σχόλια), p (διατηρεί τις μεταβλητές αντιστοίχισης· παρωχημένο από την 5.20), o (μεταγλώττιση μοτίβου μία φορά), d / u / a / l (σημασιολογία συνόλου χαρακτήρων), n (μη συλλαμβάνον εξ ορισμού). Δείτε το κεφάλαιο τροποποιητών.
Οριοθέτες#
Οποιοσδήποτε χαρακτήρας που δεν είναι λευκός μπορεί να αντικαταστήσει το /. Αν ο επιλεγμένος οριοθέτης είναι ένας από τους (, [, {, ή <, ο τελεστής λαμβάνει δύο ομάδες σε αγκύλες και ο οριοθέτης μεταξύ τους είναι προαιρετικός:
s(foo)(bar)
s{foo}{bar}
s<foo>/bar/
s[foo]{bar}g
Οι οριοθέτες με μονά εισαγωγικά απενεργοποιούν την παρεμβολή τόσο στο PATTERN όσο και στο REPLACEMENT (εκτός αν ισχύει το /e, το οποίο αναλύει πάντα το REPLACEMENT ως κώδικα):
s'$name'$value'; # literal $name → literal $value, no interpolation
Τα backticks είναι κανονικοί οριοθέτες· το s`x`y` δεν εκτελεί εντολή κελύφους.
Όταν ο οριοθέτης είναι χαρακτήρας που είναι επίσης χαρακτήρας προσδιοριστή, απαιτείται κενό μετά το s ώστε ο αναλυτής να μη το διαβάσει ως μέρος του ονόματος του τελεστή.
Παραδείγματα#
Βασική επιτόπια αντικατάσταση στο $_:
$_ = 'the quick brown fox';
s/quick/slow/; # $_ is now 'the slow brown fox'
Ρητός στόχος με =~:
my $path = '/usr/bin/perl';
$path =~ s|/usr/bin|/usr/local/bin|;
# $path is '/usr/local/bin/perl'
Καθολική αντικατάσταση, με σύλληψη του πλήθους:
my $text = 'one two two three two';
my $n = ($text =~ s/two/2/g); # $text: 'one 2 2 three 2'; $n == 3
Μη καταστροφικό /r - αφήνει την πηγή ως έχει, επιστρέφει το αντίγραφο. Ιδιωματικό σε map:
my @clean = map { s/\s+\z//r } @lines; # @lines untouched
Αξιολόγηση κώδικα με /e. Η δεξιά πλευρά είναι έκφραση Perl της οποίας η τιμή γίνεται η αντικατάσταση:
my $s = 'abc123xyz';
$s =~ s/\d+/$& * 2/e; # $s is 'abc246xyz'
my %percent = (n => "\n", t => "\t");
$s =~ s/%(.)/$percent{$1} || $&/ge; # expand %-escapes
Αλυσιδωτό /r - καθαρά συναρτησιακοί μετασχηματισμοί χωρίς ενδιάμεση μεταβλητή:
my $out = $text =~ s/foo/bar/r
=~ s/baz/qux/r;
Ομάδες σύλληψης και οπισθαναφορές στην αντικατάσταση - προσέξτε τη μορφή $1, όχι \1:
# swap the first two whitespace-separated fields
s/(\S+)\s+(\S+)/$2 $1/;
Ο ιδιωματισμός 1 while για αντικαταστάσεις που δημιουργούν νέες αντιστοιχίες:
# insert commas into an integer from the right
my $n = '1234567890';
1 while $n =~ s/(\d)(\d\d\d)(?!\d)/$1,$2/;
# $n is '1,234,567,890'
Οριακές περιπτώσεις#
Ο στόχος πρέπει να είναι βαθμωτό lvalue (εκτός αν χρησιμοποιείται το
/r): μεταβλητή, στοιχείο, ή lvalue τηςsubstr. Τοs/x/y/έναντι κυριολεκτικής συμβολοσειράς ή του αποτελέσματος μιας κλήσης συνάρτησης είναι σφάλμα κατά τη μεταγλώττιση. Υπό το/rοποιαδήποτε έκφραση είναι επιτρεπτή αφού τίποτα δεν τροποποιείται.Το κενό μοτίβο επαναχρησιμοποιεί την τελευταία επιτυχημένη αντιστοιχία. Το
s//new/αντικαθιστά έναντι όποιουPATTERNταίριαξε πιο πρόσφατα στην περικλείουσα εμβέλεια. Βολικό μέσα σεwhile (m/.../g) { s//x/ }, εκπληκτικό όταν έχει εκτελεστεί άσχετος κώδικας ενδιάμεσα.Η παρεμβολή συμβαίνει κατά τον χρόνο εκτέλεσης. Το
s/$foo/$bar/επανα-μεταγλωττίζει το μοτίβο σε κάθε κλήση αν το$fooαλλάξει. Χρησιμοποιήστε/oγια μεταγλώττιση μία φορά και πάγωμα της συλληφθείσας τιμής - ή προμεταγλωττίστε μεqr, που είναι η σύγχρονη εναλλακτική.Το
/eαναλύει την αντικατάσταση κατά τη μεταγλώττιση παρόλο που εκτελείται κατά τη στιγμή της αντιστοίχισης. Τα συντακτικά σφάλματα εμφανίζονται κατά τη φόρτωση του σεναρίου, όχι όταν πυροδοτείται η αντικατάσταση. Κάθε επιπλέονeτυλίγει μία ακόμηevalγύρω από την τιμή.Το
/gμε κενή αντιστοιχία προχωρά κατά έναν χαρακτήρα για να αποφευχθεί άπειρος βρόχος: τοs/\b/-/gεισάγει μεταξύ κάθε λεκτικού, δεν κολλάει στην πρώτη θέση.Το
!~αντιστρέφει την επιστροφή, όχι την εργασία. Το$x !~ s/A/a/gεξακολουθεί να τροποποιεί το$x· απλώς επιστρέφει αληθές όταν δεν βρέθηκε κανέναA.Η αντιστοίχιση οριοθετών για αγκύλες χρησιμοποιεί τον κατοπτρικό αντίστοιχο:
s{pat}{rep},s<pat><rep>. Ένας οριοθέτης διαφορετικός από αγκύλη πρέπει να εμφανιστεί τρεις φορές συνολικά:s/pat/rep/.Το
/cείναι no-op στοs///. Γίνεται δεκτό για συντακτική συμμετρία με τηm//· η χρήση του παράγει προειδοποίηση υπό τοuse warningsκαι τίποτε άλλο.Ιδιωματισμός ανάθεσης-ως-στόχου. Το
($copy = $src) =~ s/x/y/gγεμίζει το$copyμε την τροποποιημένη τιμή και αφήνει το$srcως έχει. Ο σύγχρονος κώδικας προτιμά τοmy $copy = $src =~ s/x/y/gr.Στόχοι tied ή υπερφορτωμένοι. Χωρίς το
/r, καλείται ηSTOREμετά την αντικατάσταση για να γραφεί η νέα τιμή πίσω· η ανακτημένη τιμή αντιγράφεται σε απλό ενταμιευτή πριν εφαρμοστεί το μοτίβο. Με το/rτο αποτέλεσμα είναι πάντα απλή συμβολοσειρά - η tie / υπερφόρτωση δεν διατηρείται στην επιστροφή.
Διαφορές από το upstream#
Πλήρως συμβατό με το upstream Perl 5.42.
Δείτε επίσης#
m//- ο τελεστής αντιστοίχισης· μοιράζεται τη σημασιολογία σημαιών πλευράς αντιστοίχισης και τους κανόνες επιστροφής έναντι περιβάλλοντοςtr///- μεταγραμματισμός χαρακτήρα προς χαρακτήρα· πολύ ταχύτερος όταν η εργασία είναι κυριολεκτική μετάφραση χαρακτήρων, όχι regexqr//- προμεταγλωττίζει ένα μοτίβο μία φορά και το παρεμβάλλει σε πολλές κλήσειςs///ήm//· η σύγχρονη εναλλακτική για το/osplit- όταν ο στόχος είναι το σπάσιμο μιας συμβολοσειράς σε ένα μοτίβο αντί για αντικατάσταση αντιστοιχιών, καταφύγετε στηsplit-
the chapter dedicated to
s///; covers/e,/r,/g,\K, and zero-length-match handling
-
the full pattern-language reference; every match-side flag on
s///is defined there
$&- το κείμενο που ταίριαξε, διαθέσιμο μέσα στοREPLACEMENTκάθεs///