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

split#

Κόβει μια συμβολοσειρά σε λίστα πεδίων χρησιμοποιώντας διαχωριστή regex.

Η split σαρώνει το EXPR για αντιστοιχίες του PATTERN και επιστρέφει τα κομμάτια μεταξύ των αντιστοιχιών ως λίστα. Το ίδιο το κείμενο που ταίριαξε είναι ο διαχωριστής και δεν περιλαμβάνεται στο αποτέλεσμα - εκτός αν το μοτίβο περιέχει ομάδες σύλληψης, οπότε κάθε σύλληψη γίνεται επιπλέον στοιχείο στην έξοδο. Σε βαθμωτό περιβάλλον επιστρέφεται το μέγεθος της λίστας.

Αν το PATTERN παραλειφθεί, η split συμπεριφέρεται όπως η προεπιλογή του awk: ακολουθίες λευκών χαρακτήρων αποτελούν τον διαχωριστή και οποιοιδήποτε προπορευόμενοι λευκοί χαρακτήρες στο EXPR αφαιρούνται. Αν το EXPR παραλειφθεί, διαχωρίζεται το $_.

Σύνοψη#

split /PATTERN/, EXPR, LIMIT
split /PATTERN/, EXPR
split /PATTERN/
split

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

Μια λίστα υποσυμβολοσειρών (πεδίων) σε περιβάλλον λίστας· το πλήθος των πεδίων σε βαθμωτό περιβάλλον. Το κείμενο του διαχωριστή δεν αποτελεί ποτέ μέρος πεδίου.

my @fields = split /,/, "a,b,c";       # ("a", "b", "c")
my $n      = split /,/, "a,b,c";       # 3

Ο διαχωρισμός ενός EXPR που είναι η κενή συμβολοσειρά πάντα αποδίδει μηδέν πεδία, ανεξαρτήτως LIMIT:

my @x = split /,/, "", -1;             # ()

Πριν την Perl 5.11, η split σε κενό ή βαθμωτό περιβάλλον αντικαθιστούσε το @_. Η σύγχρονη Perl δεν το κάνει· μην βασίζεστε ποτέ σε εκείνη την παλιά παρενέργεια.

Το όρισμα LIMIT#

Το LIMIT ελέγχει πόσα πεδία παράγονται και, το πιο κρίσιμο, αν τα κενά πεδία στο τέλος διατηρούνται.

  • Θετικό LIMIT - άνω φράγμα στον αριθμό των πεδίων. Το EXPR διαχωρίζεται το πολύ LIMIT - 1 φορές· το τελευταίο πεδίο κρατά το υπόλοιπο της συμβολοσειράς αυτούσιο. LIMIT = 1 σημαίνει κανέναν διαχωρισμό - λαμβάνετε ολόκληρη τη συμβολοσειρά ως ένα στοιχείο.

    my @x = split /,/, "a,b,c", 1;       # ("a,b,c")
    my @x = split /,/, "a,b,c", 2;       # ("a", "b,c")
    my @x = split /,/, "a,b,c", 3;       # ("a", "b", "c")
    my @x = split /,/, "a,b,c", 4;       # ("a", "b", "c")
    
  • Αρνητικό LIMIT - αντιμετωπίζεται ως αυθαίρετα μεγάλο. Παράγονται όσα περισσότερα πεδία γίνεται, συμπεριλαμβανομένων όλων των κενών πεδίων στο τέλος.

    my @x = split /,/, "a,b,c,,,", -1;   # ("a", "b", "c", "", "", "")
    
  • Παραλειπόμενο ή μηδενικό LIMIT - όπως αρνητικό, εκτός από το ότι τα κενά πεδία στο τέλος αφαιρούνται. Τα κενά πεδία στην αρχή διατηρούνται πάντα.

    my @x = split /,/, "a,b,c,,,";       # ("a", "b", "c")
    my @x = split /,/, ",,a,b";          # ("", "", "a", "b")
    
  • Έμμεσο LIMIT σε ανάθεση λίστας. Όταν γίνεται ανάθεση σε λίστα σταθερού μεγέθους, η Perl θέτει το LIMIT σε ένα παραπάνω από τον αριθμό των στόχων, ώστε τα πεδία στο τέλος να μη χρειάζεται να σαρωθούν. Το παρακάτω λαμβάνει αυτόματα LIMIT = 3:

    my ($login, $passwd) = split /:/;
    

    Σε χρονοκρίσιμο κώδικα, περάστε ρητό LIMIT αντί να αφήσετε ολόκληρη τη συμβολοσειρά να σαρωθεί.

Η περίπτωση λευκών χαρακτήρων τύπου awk: split " "#

A literal single space as the pattern - split " ", not split / /

  • triggers a special case: PATTERN is treated as /\s+/ and any leading whitespace in EXPR is stripped before splitting. This matches classic awk behaviour.

my @x = split " ", "  Quick brown fox\n";
# ("Quick", "brown", "fox")

my @x = split " ", "RED\tGREEN\tBLUE";
# ("RED", "GREEN", "BLUE")

Για διαχωρισμό σε ένα μονό κυριολεκτικό κενό μόνο, χρησιμοποιήστε τη μορφή regex / / - δεν υπόκειται σε ειδική περίπτωση:

my @x = split / /, " abc";             # ("", "abc")

Από την Perl 5.18, η ενεργοποίηση είναι οποιαδήποτε έκφραση της οποίας η τιμή είναι η συμβολοσειρά ενός χαρακτήρα " " (όχι μόνο κυριολεκτική), και από την Perl 5.28 ο κανόνας λειτουργεί σωστά υπό το use feature 'unicode_strings'. Υπό την Perl 5.39.9+ ο προεπιλεγμένος τροποποιητής /x δεν επηρεάζει το split STRING, οπότε το split " " εξακολουθεί να σημαίνει εξομοίωση awk ακόμη και μέσα σε use re "/x". Αν θέλετε να διαχωρίσετε σε ένα κυριολεκτικό κενό υπό το use re "/x", γράψτε split /(?-x: )/ ή split /\x{20}/.

Αν το PATTERN παραλειφθεί εντελώς, εξ ορισμού είναι " ", οπότε το γυμνό split αποτελεί τη μορφή τύπου awk.

Η περίπτωση κενού μοτίβου: διαχωρισμός σε χαρακτήρες#

Αν το PATTERN ταιριάζει με την κενή συμβολοσειρά, ο διαχωρισμός συμβαίνει σε κάθε θέση αντιστοιχίας - δηλαδή μεταξύ των χαρακτήρων.

my @x = split //, "abc";               # ("a", "b", "c")

Ως κανόνας ειδικός για την split, ο γυμνός τελεστής αντιστοίχισης // δεν είναι εδώ η μορφή «επανάληψε την τελευταία επιτυχημένη αντιστοιχία»· είναι το κυριολεκτικά κενό μοτίβο. Μια αντιστοιχία μηδενικού πλάτους ακριβώς στην αρχή του EXPR δεν παράγει ποτέ κενό αρχικό πεδίο, για αυτόν τον λόγο ο διαχωρισμός προπορευόμενου κενού χειρίζεται έτσι:

my @x = split //, " abc";              # (" ", "a", "b", "c")   - 4, not 5
my @x = split //, " abc", -1;          # (" ", "a", "b", "c", "") - trailing empty with -1

Μια αντιστοιχία θετικού πλάτους στην αρχή όντως παράγει κενό αρχικό πεδίο:

my @x = split / /, " abc";             # ("", "abc")

Οι ομάδες σύλληψης γίνονται επιπλέον στοιχεία#

Αν το PATTERN περιέχει ομάδες σύλληψης, κάθε σύλληψη εισάγεται στη λίστα εξόδου για κάθε αντιστοιχία διαχωριστή, με τη σειρά που δηλώνονται οι ομάδες. Μια ομάδα που δεν συμμετέχει στην αντιστοιχία συνεισφέρει undef. Αυτά τα επιπλέον στοιχεία δεν μετρούν για το LIMIT.

my @x = split /-|,/    , "1-10,20", 3;
# ("1", "10", "20")

my @x = split /(-|,)/  , "1-10,20", 3;
# ("1", "-", "10", ",", "20")

my @x = split /-|(,)/  , "1-10,20", 3;
# ("1", undef, "10", ",", "20")

my @x = split /(-)|,/  , "1-10,20", 3;
# ("1", "-", "10", undef, "20")

my @x = split /(-)|(,)/, "1-10,20", 3;
# ("1", "-", undef, "10", undef, ",", "20")

Χρησιμοποιήστε αυτό όταν θέλετε οι διαχωριστές να διατηρούνται μαζί με τα πεδία - τυπικό για tokenisers όπου οι οριοθέτες αποτελούν οι ίδιοι μέρος του ρεύματος εξόδου.

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

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

  • @_ - η σύγχρονη Perl δεν το αγγίζει. Σχετικό μόνο αν υποστηρίζετε perl πριν την 5.11.

  • Οι μεταβλητές αντιστοίχισης της μηχανής regex ($1, $2, …, $&, $', $``) **δεν** ορίζονται ως παρενέργεια της split, ακόμη και όταν το PATTERN` συλλαμβάνει - οι συλλήψεις πηγαίνουν στη λίστα επιστροφής.

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

Κλασική γραμμή τύπου CSV, χωρίς ενσωματωμένα κόμματα:

my @cells = split /,/, "alice,bob,carol";    # ("alice", "bob", "carol")

Ανάλυση μιας γραμμής /etc/passwd σε γνωστά πεδία· το έμμεσο LIMIT σταματά στους πρώτους επτά διαχωριστές:

my ($user, $pw, $uid, $gid, $gecos, $home, $shell)
    = split /:/, $line;

Tokenising λευκών χαρακτήρων τύπου awk, με τα προπορευόμενα κενά να απορρίπτονται:

my @words = split " ", "   one\ttwo  three\n";
# ("one", "two", "three")

Χαρακτήρες μιας συμβολοσειράς - το κενό μοτίβο:

my @chars = split //, "hello";               # ("h", "e", "l", "l", "o")

Διατήρηση κάθε κενού πεδίου στο τέλος για αυστηρό αναγνώστη μετρήματος στηλών:

my @cols = split /\t/, $line, -1;

Διατήρηση των διαχωριστών μέσω σύλληψης - αναπαραγωγή με round-trip:

my @parts = split /([,;])/, "a,b;c";         # ("a", ",", "b", ";", "c")
my $same  = join "", @parts;                 # "a,b;c"

Η προεπιλεγμένη μορφή διαβάζει το $_ και κάνει διαχωρισμό λευκών χαρακτήρων τύπου awk:

for (@lines) {
    my @f = split;                           # split " ", $_
    ...
}

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

  • Κενή είσοδος - το split /X/, "" επιστρέφει την κενή λίστα για κάθε LIMIT, συμπεριλαμβανομένου του -1.

  • LIMIT = 1 - δεν γίνεται διαχωρισμός· ολόκληρη η συμβολοσειρά είναι το ένα και μοναδικό πεδίο. Χρήσιμο όταν θέλετε τη σημασιολογία της split υπό συνθήκη χωρίς να χάσετε την είσοδο.

  • Μοτίβο /^/ - αντιμετωπίζεται σαν /^/m ώστε να ταιριάζει στην αρχή κάθε γραμμής, που είναι η μόνη χρήσιμη συμπεριφορά. Διαχωρίζει μια συμβολοσειρά σε γραμμές διατηρώντας τις νέες γραμμές.

  • Αντιστοιχία μηδενικού πλάτους στη θέση 0 - δεν παράγει ποτέ κενό αρχικό πεδίο (δείτε split //, " abc" παραπάνω).

  • Αντιστοιχία θετικού πλάτους στη θέση 0 - παράγει κενό αρχικό πεδίο, πάντα.

  • Αντιστοιχία στο τέλος της συμβολοσειράς - παράγει κενό πεδίο στο τέλος, το οποίο στη συνέχεια αφαιρείται εκτός αν το LIMIT είναι μη μηδενικό.

  • Μοτίβα με τροποποιητές - εφαρμόζονται οι συνήθεις τροποποιητές qr// (/i, /m, /s, /x, /u, /a, /l, /n). Το μοτίβο δεν χρειάζεται να είναι κυριολεκτικό· οποιαδήποτε έκφραση που παράγει regex ή συμβολοσειρά λειτουργεί, και τα αντικείμενα qr// γίνονται δεκτά.

  • Συμβολοσειρά μονού κενού που δεν είναι κυριολεκτική - από την Perl 5.18 και μετά, οποιαδήποτε έκφραση που αξιολογείται σε " " ενεργοποιεί την ειδική περίπτωση τύπου awk, όχι μόνο το κυριολεκτικό " ".

  • split " " έναντι split / / - το πρώτο είναι λευκοί χαρακτήρες τύπου awk (\s+ με αφαίρεση των προπορευόμενων κενών), το δεύτερο είναι ένα κυριολεκτικό μονό κενό. Τα δύο δεν είναι ανταλλάξιμα.

  • Λευκοί χαρακτήρες Unicode - υπό το use feature 'unicode_strings' (προεπιλογή από την 5.28 για την περίπτωση τύπου awk), το split " " αντιμετωπίζει και τους λευκούς χαρακτήρες Unicode ως διαχωριστή. Έξω από αυτή την εμβέλεια η συμπεριφορά επηρεάζεται από το «Unicode Bug».

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

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

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

  • join - αντίστροφη πράξη· συρράπτει μια λίστα ξανά σε συμβολοσειρά με επιλεγμένη κόλλα

  • m - ο τελεστής αντιστοίχισης· όταν θέλετε να βρείτε κάτι αντί να κόψετε τη συμβολοσειρά γύρω από αυτό

  • qr - προμεταγλώττιση μοτίβου μία φορά για επανειλημμένες κλήσεις split σε καυτό βρόχο

  • index - εντοπισμός σταθερής υποσυμβολοσειράς χωρίς κατασκευή της πλήρους λίστας πεδίων· φθηνότερο όταν χρειάζεστε μόνο τον πρώτο διαχωρισμό

  • substr - εξαγωγή με μετατόπιση byte/χαρακτήρα όταν τα όρια των πεδίων είναι θέσεις, όχι οριοθετημένα