Βαθμωτά και συμβολοσειρές

q//#

Συμβολοσειρά με μονά εισαγωγικά και ελεύθερη επιλογή οριοθέτη.

Η q// είναι η γενική μορφή της συνηθισμένης συμβολοσειράς '...'. Παράγει μια σταθερά συμβολοσειράς κατά τη μεταγλώττιση, δεν παρεμβάλλει μεταβλητές και δεν επεξεργάζεται τις ακολουθίες διαφυγής με ανάστροφη κάθετο που αναγνωρίζουν η qq// και τα regex literals. Καταφύγετε στην q// όποτε το literal που θέλετε να γράψετε θα ήταν δύσχρηστο υπό την '...' - συνηθέστερα επειδή η ίδια η συμβολοσειρά περιέχει μονά εισαγωγικά - ή όταν ένας διαφορετικός οριοθέτης απλώς διαβάζεται καλύτερα στο πλαίσιο.

Σύνοψη#

q/STRING/
q(STRING)
q[STRING]
q{STRING}
q<STRING>
q!STRING!
q#STRING#
'STRING'

Οποιοσδήποτε μη αλφαριθμητικός χαρακτήρας λειτουργεί ως οριοθέτης. Τα τέσσερα ζεύγη αγκυλών ASCII ((), [], {}, <>) εμφωλεύονται· όλοι οι άλλοι οριοθέτες όχι. Η '...' είναι σύντμηση για το q(...) με ταυτόσημη σημασιολογία.

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

Μια συμβολοσειρά σε βαθμωτό περιβάλλον - η ακριβής ακολουθία bytes μεταξύ του οριοθέτη ανοίγματος και κλεισίματος, με δύο επανεγγραφές:

  • Το \\ γίνεται μία ανάστροφη κάθετος.

  • Το \<delim> γίνεται κυριολεκτικό αντίγραφο του χαρακτήρα οριοθέτη (αυτό σας επιτρέπει να συμπεριλάβετε τον οριοθέτη μέσα στο σώμα).

Κάθε άλλος χαρακτήρας, περιλαμβανομένης κάθε άλλης \, μένει κατά λέξη. Δεν υπάρχει \n, ούτε \t, ούτε επέκταση $var, ούτε \x{...}, ούτε \N{...} - το εσωτερικό της q// πλησιάζει όσο μπορεί η Perl στο «ό,τι πληκτρολογήσατε, αυτό παίρνετε».

Σε περιβάλλον λίστας, η q// εξακολουθεί να αποτιμάται στην ίδια μοναδική συμβολοσειρά.

Οριοθέτες και εμφώλευση#

Οι μη αγκύλωτοι οριοθέτες χρησιμοποιούν τον ίδιο χαρακτήρα στην αρχή και στο τέλος:

my $a = q!I said, "You said, 'She said it.'"!;
my $b = q/path/to/file/;   # WRONG - ends at the second "/"
my $b = q{path/to/file};   # RIGHT - braces nest, slashes are literal

Οι αγκυλωτοί οριοθέτες εμφωλεύονται, οπότε ισορροπημένες αγκύλες μέσα στο σώμα είναι εντάξει και μόνο ένα μη ισορροπημένο κλείσιμο τερματίζει τη συμβολοσειρά:

my $c = q{foo{bar}baz};    # "foo{bar}baz"
my $d = q(f(o(o)b)ar);     # "f(o(o)b)ar"

Οι λευκοί χαρακτήρες μεταξύ της q και του οριοθέτη επιτρέπονται εκτός όταν ο οριοθέτης είναι # - το q#foo# είναι η συμβολοσειρά "foo", αλλά το q #foo# είναι ο τελεστής q ακολουθούμενος από σχόλιο γραμμής, και το σώμα της συμβολοσειράς συνεχίζεται στην επόμενη γραμμή. Όταν ο οριοθέτης είναι χαρακτήρας λέξης (ταιριάζει με /\w/), οι λευκοί χαρακτήρες μεταξύ της q και του οριοθέτη είναι υποχρεωτικοί: το q XfooX είναι "foo", ενώ το qXfooX αποτελεί συντακτικό σφάλμα.

Κανόνες διαφυγής#

Μέσα στην q// η ανάστροφη κάθετος έχει ακριβώς δύο ειδικούς ρόλους:

Ακολουθία

Παράγει

\\

μία ανάστροφη κάθετο

\<delim>

κυριολεκτικό αντίγραφο του οριοθέτη

Οτιδήποτε άλλο ξεκινά με \ παραμένει ως δύο χαρακτήρες:

print q(\n), "\n";       # prints "\n" then a real newline
print length q(\n);      # 2
print q(\t\r\0);         # prints "\t\r\0" - six characters

Αυτή είναι η πιο συχνή πηγή σύγχυσης για όσους έρχονται από συμβολοσειρές με διπλά εισαγωγικά - στην q// και στην '...', το \n είναι μια ανάστροφη κάθετος ακολουθούμενη από το γράμμα n, όχι χαρακτήρας νέας γραμμής.

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

Ενσωμάτωση και των δύο εισαγωγικών χωρίς διαφυγή:

my $msg = q{I said "hello", she said 'hi'.};

Διαδρομή τύπου Windows, όπου οι ανάστροφες κάθετοι είναι άφθονες και η παρεμβολή με διπλά εισαγωγικά θα ήταν κίνδυνος:

my $path = q(C:\Users\alice\Documents);
print $path;                 # C:\Users\alice\Documents

Ένα κυριολεκτικό $ χωρίς παρεμβολή - η qq// θα απαιτούσε διαφυγή κάθε $ και @, η q// τα αφήνει ως έχουν:

my $expr = q($total = $x + $y);
print $expr;                 # $total = $x + $y

Ο μοναδικός τρόπος να βάλετε τον οριοθέτη μέσα στο σώμα: διαφυγή του με ανάστροφη κάθετο. Σημειώστε ότι η ίδια η ανάστροφη κάθετος καταναλώνεται.

my $s = q!He said "ouch\!" loudly!;
print $s;                    # He said "ouch!" loudly

Ένα μοτίβο regex αποθηκευμένο ως απλή συμβολοσειρά, που μεταβιβάζεται σε qr// στο σημείο χρήσης - η q// κρατά τις ανάστροφες κάθετους κυριολεκτικές ώστε το μοτίβο να επιβιώσει ακέραιο:

my $pat = q(\d{3}-\d{4});
if ($phone =~ /$pat/) { ... }

Πολυγραμμικό literal χωρίς επεξεργασία διαφυγής - κάθε αλλαγή γραμμής στην πηγή γίνεται αλλαγή γραμμής στη συμβολοσειρά:

my $sql = q{
    SELECT id, name
    FROM   users
    WHERE  active = 1
};

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

  • Η q// είναι μεταγλώττισης. Ο αναλυτής επιλύει τη συμβολοσειρά όταν διαβάζεται η πηγή· δεν υπάρχει κόστος χρόνου εκτέλεσης πέρα από τη χρήση της ήδη κατασκευασμένης σταθεράς. Όπως και η '...'.

  • Οι '...' και q(...) είναι αδιαφοροποίητες μετά τη συντακτική ανάλυση. Η επιλογή είναι αμιγώς θέμα ύφους - διαλέξτε όποια διαβάζεται καλύτερα για το περιεχόμενο.

  • Κενή συμβολοσειρά. Τόσο το q() όσο και το '' δίνουν τη συμβολοσειρά μηδενικού μήκους.

  • Κανένα \n, κανένα \t, καμία παρεμβολή, ποτέ. Αν χρειάζεστε κάτι από αυτά, μεταβείτε σε qq// ή "...". Η ανάμιξη των δύο στην ίδια γραμμή είναι εντάξει: q(literal ) . qq(interpolated $x).

  • Ανάστροφη κάθετος στο τέλος του σώματος. Μία \ αμέσως πριν τον οριοθέτη κλεισίματος τον διαφεύγει, οπότε το q(foo\) είναι συντακτικό σφάλμα - το \) γίνεται κυριολεκτικό ) και η συμβολοσειρά μένει χωρίς τερματισμό. Γράψτε q(foo\\) για να τελειώσετε μια συμβολοσειρά με μία ανάστροφη κάθετο.

  • Μη ισορροπημένες αγκύλες με αγκυλωτούς οριοθέτες. Επειδή οι αγκύλες εμφωλεύονται, το q{foo{bar} αποτελεί συντακτικό σφάλμα - η εσωτερική { ανοίγει εμφωλευμένο επίπεδο και η εξωτερική } το κλείνει, αφήνοντας τη συμβολοσειρά χωρίς τερματισμό. Χρησιμοποιήστε μη αγκυλωτό οριοθέτη, ή ισορροπήστε τις αγκύλες, ή διαφύγετε μία από αυτές: q{foo\{bar}.

  • Το # ως οριοθέτης δεν χρειάζεται κενό από την q, αλλά κάθε άλλος οριοθέτης που είναι χαρακτήρας λέξης (γράμματα, ψηφία, _) απαιτεί λευκό χαρακτήρα μεταξύ της q και του οριοθέτη ανοίγματος.

  • Η εισαγωγή κώδικα Perl σε εισαγωγικά είναι εύθραυστη. Το q{ if ($x eq "}") { ... } } αποτελεί συντακτικό σφάλμα: η } μέσα στην ενσωματωμένη συμβολοσειρά με διπλά εισαγωγικά κλείνει το εξωτερικό άγκιστρο πριν η Perl δει την εσωτερική συμβολοσειρά. Εργαλεία όπως το Text::Balanced υπάρχουν επειδή το χειρόγραφο γράψιμο αξιόπιστου quoter για πηγαία Perl είναι δυσάρεστο.

  • Ασάφεια αναλυτή με / ως οριοθέτη. Η q/.../ χρησιμοποιεί τη / με τον ίδιο τρόπο που τη χρησιμοποιεί η m//. Μέσα στο σώμα δεν ισχύει σύνταξη regex, αλλά μια πλάγια κάθετος στο περιεχόμενο θα τερματίσει τη συμβολοσειρά πρόωρα - επιλέξτε διαφορετικό οριοθέτη (q{...}, q(...)) όταν εμφανίζονται πλάγιες καθέτους στο κείμενο.

  • Τα heredocs με <<'TAG' ακολουθούν τους ίδιους κανόνες διαφυγής με την q//: καμία παρεμβολή, καμία επεξεργασία διαφυγής πέραν της \\ και του ότι το \TAG δεν είναι ειδικό (το tag τερματίζει στη δική του γραμμή). Χρησιμοποιήστε heredoc με μονά εισαγωγικά όταν θέλετε σημασιολογία q// σε πολλές γραμμές χωρίς οριοθέτη κλεισίματος στη μέση του κειμένου.

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

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

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

  • qq// - literal διπλών εισαγωγικών· ίδια ευελιξία οριοθέτη με την q// συν παρεμβολή μεταβλητών και το πλήρες λεξιλόγιο διαφυγής \n/\t/\x{...}

  • qw// - λίστα λέξεων χωρισμένων με λευκούς χαρακτήρες· αυτό που θέλετε όταν το literal είναι λίστα σύντομων tokens, όχι μία συμβολοσειρά

  • qr// - μεταγλώττιση literal regex· το μέλος της οικογένειας quote-like που αφορά αντιστοίχιση μοτίβων

  • qx// - εκτελεί μια εντολή στο κέλυφος και συλλαμβάνει την έξοδό της· ίδιοι κανόνες οριοθέτη, σημασιολογία ανάστροφων εισαγωγικών

  • quotemeta - αντίστοιχο σε χρόνο εκτέλεσης του \Q...\E, χρήσιμο όταν χρειάζεται να τροφοδοτήσετε ένα literal q// σε regex ως σταθερή συμβολοσειρά

  • $" - διαχωριστής λίστας που χρησιμοποιείται όταν πίνακες παρεμβάλλονται μέσα σε qq//· άσχετο με την ίδια την q//, αλλά ο συνηθισμένος λόγος που κάποιος καταφεύγει στην q// είναι ακριβώς για να αποφύγει αυτόν τον μηχανισμό