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

quotemeta#

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

Η quotemeta υπάρχει για να γεφυρώσει δεδομένα συμβολοσειράς και σύνταξη regex. Όταν είσοδος χρήστη, ονόματα αρχείων ή τιμές διαμόρφωσης καταλήγουν στη δεξιά πλευρά του =~, οποιοσδήποτε χαρακτήρας τυχαίνει να είναι μεταχαρακτήρας regex (., *, +, ?, (, [, \, |, …) θα ενεργοποιούσε αλλιώς την ειδική του συμπεριφορά. Η quotemeta το προλαβαίνει εισάγοντας μια ανάστροφη πλαγιοκάθετο πριν από κάθε ASCII μη-λεκτικό χαρακτήρα, αφήνοντας γράμματα, ψηφία και κάτω παύλα άθικτα.

Σύνοψη#

quotemeta EXPR
quotemeta

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

Μια νέα συμβολοσειρά. Κάθε χαρακτήρας ASCII που δεν ταιριάζει στο /[A-Za-z_0-9]/ προηγείται από ανάστροφη πλαγιοκάθετο· οι λεκτικοί χαρακτήρες περνούν αμετάβλητοι. Το αποτέλεσμα είναι πάντα ασφαλές να επικολληθεί σε regex ως κυριολεκτικό κομμάτι μοτίβου.

Η quotemeta είναι καθαρός παραγωγός τιμής - δεν τροποποιεί το όρισμά της.

my $safe = quotemeta 'a.b*c';     # 'a\.b\*c'

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

Διαβάζει την $_ όταν καλείται χωρίς όρισμα. Εντός της εμβέλειας του use locale, επιπλέον μη-ASCII χαρακτήρες Latin‑1 διαφυγαίνονται για προστασία απέναντι σε locale που αντιμετωπίζουν στίξη όπως το | ως λεκτικό χαρακτήρα.

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

Η σκέτη μορφή υποχωρεί στην $_, όπως οι περισσότερες ενσωματωμένες συναρτήσεις λίστας:

for ('a+b', 'c.d') {
    print quotemeta, "\n";     # a\+b
}                              # c\.d

Παρεμβολή εισόδου χρήστη σε αντικατάσταση. Χωρίς την quotemeta, το .*? μέσα στο $substring θα ήταν ενεργό ως regex και θα ταίριαζε πολύ περισσότερα από όσο σκόπευε:

my $sentence  = 'The quick brown fox jumped over the lazy dog';
my $substring = 'quick.*?fox';
my $quoted    = quotemeta $substring;
$sentence =~ s{$quoted}{big bad wolf};
# $sentence unchanged - the literal text 'quick.*?fox' is not present

Η ακολουθία διαφυγής \Q...\E σε διπλά-εισαγωγικά συμβολοσειρά είναι ακριβώς η quotemeta εφαρμοσμένη στην περικλειόμενη περιοχή. Οι δύο παρακάτω μορφές είναι ισοδύναμες:

my $pat1 = "\Q$substring\E";
my $pat2 = quotemeta($substring);

Δόμηση regex που ταιριάζει κυριολεκτικό όνομα αρχείου οπουδήποτε σε διαδρομή:

my $name = 'my.config[prod].ini';
if ($path =~ /\Q$name\E\z/) {
    # matches exactly the filename, no metachar surprises
}

Διαφυγή λίστας όρων για εναλλαγή:

my @terms = ('C++', 'C#', '.NET');
my $alt   = join '|', map { quotemeta } @terms;
# 'C\+\+|C\#|\.NET'

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

  • Χωρίς όρισμα: η quotemeta χωρίς έκφραση διαφυγαίνει την $_. Μέσα σε βρόχο όπως for (@input) { push @safe, quotemeta } αυτή είναι η ιδιωματική μορφή.

  • Οι ήδη ασφαλείς συμβολοσειρές δεν θίγονται: είσοδος αμιγώς λεκτικών χαρακτήρων ([A-Za-z0-9_]+) γυρίζει πλήρη κύκλο πανομοιότυπα.

  • Οι κυριολεκτικές ανάστροφες πλαγιοκάθετοι μέσα σε \Q...\E αλληλεπιδρούν με την παρεμβολή ανάστροφης πλαγιοκαθέτου διπλών-εισαγωγικών πριν προλάβει το \Q να δει το κείμενο. Μια ακολουθία όπως "\Q\t\E" διαφυγαίνει έναν κυριολεκτικό χαρακτήρα tab, όχι ανάστροφη πλαγιοκάθετο ακολουθούμενη από t. Όταν χρειάζεστε πραγματικές ανάστροφες πλαγιοκάθετους στη διαφυγαμένη περιοχή, κρατήστε τα δεδομένα σε μεταβλητή και χρησιμοποιήστε quotemeta $var αντί να τα ενσωματώσετε σε κυριολεκτικό διπλών-εισαγωγικών.

  • Δεν υπάρχει τρόπος να εισαχθεί κυριολεκτικό $ ή @ μέσα σε \Q...\E: ένα προστατευμένο \$ γίνεται η τεσσάρων χαρακτήρων ακολουθία \\\$ στην έξοδο, και ένα μη προστατευμένο $ ξεκινά παρεμβολή βαθμωτού πριν εκτελεστεί το \Q. Βγείτε από τη διαφυγαμένη περιοχή για να εισαγάγετε sigils.

  • Διαφυγή ενήμερη Unicode (Perl 5.16+): σε συμβολοσειρές UTF‑8 - και σε συμβολοσειρές bytes υπό use feature 'unicode_strings' ή use v5.12 ή νεότερο - οι μη-ASCII χαρακτήρες διαφυγαίνονται μόνο όταν φέρουν τις ιδιότητες Unicode Pattern_Syntax, Pattern_White_Space, White_Space, Default_Ignorable_Code_Point ή General_Category=Control. Οι χαρακτήρες κλάσης αναγνωριστικού (γράμματα, σημάδια, ψηφία) μένουν ανέγγιχτοι. Αυτό είναι το σταθερό συμβόλαιο: η Perl υπόσχεται ότι κάθε μελλοντικός μεταχαρακτήρας regex θα έχει ορισμένη την Pattern_Syntax, οπότε οι συμβολοσειρές που είναι ασφαλείς σήμερα παραμένουν ασφαλείς.

  • Παλαιές μη-UTF‑8 συμβολοσειρές εκτός εμβέλειας unicode_strings έχουν κάθε άνω-Latin‑1 κωδικοσημείο (\x80\xFF) διαφυγαμένο, για συμβατότητα προς τα πίσω με τη συμπεριφορά πριν την 5.16.

  • Διαφυγή locale: εντός use locale, όλα τα μη-ASCII κωδικοσημεία Latin‑1 διαφυγαίνονται είτε η συμβολοσειρά είναι UTF‑8 είτε όχι. Η διαφυγή εύρους ASCII δεν επηρεάζεται από locale.

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

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

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

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

  • qr - μεταγλωττισμένα αντικείμενα regex· η qr/\Q$var\E/ είναι ο συνήθης τρόπος καρφώματος ενός μοτίβου γύρω από μια κυριολεκτική συμβολοσειρά

  • s - αντικατάσταση· το συνηθέστερο σημείο διαφυγής τύπου quotemeta στο αριστερό μοτίβο

  • \Q and \E - το ζεύγος διαφυγής διπλών-εισαγωγικών που είναι απλώς η quotemeta με διαφορετική σύνταξη

  • $_ - προεπιλεγμένη είσοδος όταν η quotemeta καλείται χωρίς όρισμα