Διαδρομές
/
Julia
Julia
/
Ύλη
/
Συμβολοσειρές
Συ

Συμβολοσειρές σε Julia

7 ασκήσεις

Σχετικά με την έννοια Συμβολοσειρές

Μια String στη Julia είναι μια διατεταγμένη ακολουθία χαρακτήρων. Όπως επισημαίνει το εγχειρίδιο: "Φυσικά, το πραγματικό πρόβλημα αρχίζει όταν κάποιος ρωτήσει τι είναι ένας χαρακτήρας."

Μεγάλο μέρος αυτής της πολυπλοκότητας θα καλυφθεί με περισσότερες λεπτομέρειες στην έννοια Chars, αλλά εν συντομία:

  • Όλες οι συμβολοσειρές στη Julia είναι Unicode.
  • Οι συμβολοσειρές που τυγχάνει να είναι και ASCII (αγγλικά γράμματα από το A έως το Z κεφαλαία και πεζά, ψηφία και μερικοί χαρακτήρες στίξης) είναι εύκολες στη χρήση.
  • Τα περισσότερα άλλα συστήματα γραφής του κόσμου είναι δυνατόν να χρησιμοποιηθούν, αλλά χρειάζονται περισσότερη προσοχή.

Κυριολεκτικές συμβολοσειρές

Γενικά, οι συμβολοσειρές περικλείονται σε διπλά εισαγωγικά " ". Τα μονά εισαγωγικά ' ' χρησιμοποιούνται μόνο για Chars.

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

julia> """
       Multiline
       String
       """
"Multiline\nString\n"

Διαφυγή χαρακτήρων

Όπως οι περισσότερες γλώσσες από τη C και μετά, η Julia χρησιμοποιεί την ανάποδη κάθετο \ για διαφυγή:

  1. Για να εισάγεις χαρακτήρες που δεν εκτυπώνονται, όπως τον χαρακτήρα αλλαγής γραμμής \n στο προηγούμενο παράδειγμα.
  2. Για να προστατεύσεις χαρακτήρες που διαφορετικά θα είχαν ειδική σημασία, όπως το \$ (δες παρακάτω).

Επανάληψη

Μια συμβολοσειρά είναι μια συλλογή που μπορείς να διατρέξεις, οπότε ένας βρόχος for ... in θα δουλέψει χωρίς να χρειάζεται καμία μετατροπή σε διάνυσμα χαρακτήρων.

julia> s = "Julia"
"Julia"

# admittedly, this is a silly example
julia> for c in s; print(c, "; "); end
J; u; l; i; a; 

Η επανάληψη με αυτόν τον τρόπο έχει το πλεονέκτημα ότι η Julia θα χειριστεί σωστά τα όρια των χαρακτήρων, ακόμη και για συμβολοσειρές που δεν είναι ASCII. Η σημασία αυτού θα γίνει πιο ξεκάθαρη στην επόμενη ενότητα.

Προσπέλαση με θέση

Κατ' αρχήν, οι συμβολοσειρές μπορούν να προσπελαστούν με θέση ακριβώς όπως τα διανύσματα:

julia> s[1], s[5]
('J', 'a')

Αυτό σαφώς δουλεύει για μια συμβολοσειρά ASCII όπως η "Julia", αλλά αγνοεί τις περισσότερες γλώσσες του κόσμου.

Σκέψου έναν από τους χαρακτήρες στο Beowulf, γραμμένο στα παλαιά αγγλικά πριν από περίπου 15 αιώνες.

Το "Hrōðgār" έχει σαφώς 7 χαρακτήρες, αλλά δεν είναι όλοι τους ASCII.

julia> king = "Hrōðgār"
"Hrōðgār"

julia> length(king)
7

julia> isascii(king)
false

# collect() converts to a Char vector:
julia> collect(king)
7-element Vector{Char}:
 'H': ASCII/Unicode U+0048 (category Lu: Letter, uppercase)
 'r': ASCII/Unicode U+0072 (category Ll: Letter, lowercase)
 'ō': Unicode U+014D (category Ll: Letter, lowercase)
 'ð': Unicode U+00F0 (category Ll: Letter, lowercase)
 'g': ASCII/Unicode U+0067 (category Ll: Letter, lowercase)
 'ā': Unicode U+0101 (category Ll: Letter, lowercase)
 'r': ASCII/Unicode U+0072 (category Ll: Letter, lowercase)

Η προσπέλαση με θέση σε μια τέτοια συμβολοσειρά ξεκινάει καλά, αλλά κάποια στιγμή καταρρέει:

julia> king[3]
'ō': Unicode U+014D (category Ll: Letter, lowercase)

julia> king[4]
ERROR: StringIndexError: invalid index [4], valid nearby indices [3]=>'ō', [5]=>'ð'

Το πρόβλημα είναι ότι η προσπέλαση με θέση όπως εδώ μετράει bytes, τα οποία για συμβολοσειρές που δεν είναι ASCII δεν έχουν σχέση 1:1 με τους χαρακτήρες. Ένας χαρακτήρας Unicode/UTF-8 μπορεί να χρειάζεται έως και 4 bytes για να αναπαρασταθεί, και η έννοια Chars θα το εξερευνήσει περαιτέρω.

Κατασκευή συμβολοσειρών

Συνένωση

Πολλές γλώσσες χρησιμοποιούν το + ως τελεστή συνένωσης συμβολοσειρών, αλλά όχι η Julia. Τουλάχιστον το μήνυμα σφάλματος είναι κατατοπιστικό.

julia> "s1 " + "s2"
ERROR: MethodError: no method matching +(::String, ::String)
The function `+` exists, but no method is defined for this combination of argument types.
String concatenation is performed with * 

julia> "s1 " * "s2"
"s1 s2"

Η συνάρτηση string() συνενώνει έναν αυθαίρετο αριθμό συμβολοσειρών.

julia> string("lots ", "of ", "bits")
"lots of bits"

Η συνάρτηση join() κάνει το ίδιο, και επίσης δέχεται ένα διάνυσμα συμβολοσειρών και τις συνενώνει με έναν δεδομένο διαχωριστή (με προεπιλογή το "").

julia> join(["lots", "of", "bits"], "_")
"lots_of_bits"

Σημείωσε ότι οι συμβολοσειρές είναι αμετάβλητες, και η συνένωση περιλαμβάνει αντιγραφή. Έτσι, οι επαναλαμβανόμενες συνενώσεις μέσα σε έναν βρόχο είναι αναποτελεσματικές, και είναι καλύτερα να συγκεντρώσεις τα κομμάτια σε ένα διάνυσμα και να τα ενώσεις όλα στο τέλος.

Επανάληψη

Απλό:

julia> repeat("Abc", 5)
"AbcAbcAbcAbcAbc"

Παρεμβολή

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

Στη Julia, οι τιμές που παρεμβάλλονται προηγούνται από το $.

julia> myvar = 42
42

julia> "myvar evaluates to $myvar"
"myvar evaluates to 42"

julia> r = 5.3
5.3

julia> "A circle of radius $r has area $(π * r^2)"
"A circle of radius 5.3 has area 88.24733763933729"

Οι παρενθέσεις απαιτούνται όταν η παράλειψή τους θα ήταν διφορούμενη, αλλά είναι προαιρετικές για ένα μόνο αναγνωριστικό που ακολουθείται από κενό διάστημα.

Για να συμπεριλάβεις ένα $ μέσα στη συμβολοσειρά, γράψ' το με διαφυγή ως \$.

Πρόσεξε τον περιορισμό ότι η παρεμβολή προς το παρόν δεν επιτρέπει μορφοποίηση, όπως τον αριθμό των δεκαδικών ψηφίων που θα εμφανιστούν.

Μερικές λύσεις είναι:

  • Τύλιξε τον υπολογισμό σε μια συνάρτηση round().
  • Έξω από τον εκτελεστή δοκιμών του Exercism, το πακέτο PyFormattedStrings μιμείται τα f-strings της Python.
  • Η μακροεντολή @sprintf() περιγράφεται παρακάτω.

@sprintf()

Για πιο λεπτομερή έλεγχο στη σύνθεση συμβολοσειρών, η Julia αντιγράφει τη συνάρτηση sprintf από τη C (και από αρκετές μεταγενέστερες γλώσσες: η Wikipedia απαριθμεί περίπου 30).

Στη Julia, αυτό υλοποιείται ως macro μέσα στο module Printf, εξ ου και το πρόθεμα @.

julia> using Printf

julia> r = 5.3
5.3

julia> @sprintf("A circle of radius %.1f has area %.2f", r, π * r^2)
"A circle of radius 5.3 has area 88.25"

Συναρτήσεις συμβολοσειρών

Για απλότητα, αυτή η ενότητα θα επικεντρωθεί σε συναρτήσεις που επιστρέφουν μια νέα συμβολοσειρά και αφήνουν την είσοδο αμετάβλητη. Πολλές έχουν μια ισοδύναμη, με κατάληξη !, που τροποποιεί την είσοδο επί τόπου.

Μήκος

Πόσο μακριά είναι μια συμβολοσειρά; Μερικές φορές εξαρτάται από το πώς μετράς.

Η απλή περίπτωση είναι οι συμβολοσειρές ASCII, όπου κάθε χαρακτήρας καταλαμβάνει 1 byte.

julia> string_asc = "Julia"
"Julia"

julia> length(string_asc)
5

julia> sizeof(string_asc)
5

Η συνάρτηση length() επιστρέφει τον αριθμό των χαρακτήρων, και η συνάρτηση sizeof() τον αριθμό των bytes.

Αυτή η διάκριση γίνεται σημαντική με άλλα σύνολα χαρακτήρων:

julia> king = "Hrōðgār"
"Hrōðgār"

julia> length(king)
7

julia> sizeof(king)
10

Διαχωρισμός

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

Γενικότερα, χρησιμοποιούμε τη συνάρτηση split(). Ο διαχωριστής έχει ως προεπιλογή (οποιοδήποτε) κενό διάστημα, αλλά μπορείς να ορίσεις άλλους.

julia> split("my little string")
3-element Vector{SubString{String}}:
 "my"
 "little"
 "string"

julia> split("My_snake_case_string", "_")
4-element Vector{SubString{String}}:
 "My"
 "snake"
 "case"
 "string"

Αυτά τα παραδείγματα σπάζουν μια συμβολοσειρά σε μικρότερες συμβολοσειρές. Το σπάσιμο μιας συμβολοσειράς σε χαρακτήρες είναι διαφορετική πράξη.

julia> collect("input string")
12-element Vector{Char}:
 'i': ASCII/Unicode U+0069 (category Ll: Letter, lowercase)
 'n': ASCII/Unicode U+006E (category Ll: Letter, lowercase)
 'p': ASCII/Unicode U+0070 (category Ll: Letter, lowercase)
 'u': ASCII/Unicode U+0075 (category Ll: Letter, lowercase)
 't': ASCII/Unicode U+0074 (category Ll: Letter, lowercase)
 ' ': ASCII/Unicode U+0020 (category Zs: Separator, space)
 's': ASCII/Unicode U+0073 (category Ll: Letter, lowercase)
 't': ASCII/Unicode U+0074 (category Ll: Letter, lowercase)
 'r': ASCII/Unicode U+0072 (category Ll: Letter, lowercase)
 'i': ASCII/Unicode U+0069 (category Ll: Letter, lowercase)
 'n': ASCII/Unicode U+006E (category Ll: Letter, lowercase)
 'g': ASCII/Unicode U+0067 (category Ll: Letter, lowercase)

Εύρεση και αντικατάσταση

Περιέχει μια συμβολοσειρά μια δεδομένη υποσυμβολοσειρά; Παραδόξως, υπάρχουν δύο συναρτήσεις για να το ελέγξεις: οι occursin() και contains() διαφέρουν μόνο στη σειρά των ορισμάτων τους.

julia> needle = "Julia"
"Julia"

julia> haystack = "Python, Julia and R"
"Python, Julia and R"

julia> occursin(needle, haystack)
true

julia> contains(haystack, needle)
true

Για να είσαι πιο συγκεκριμένος ως προς τη θέση:

julia> startswith(haystack, "Python")
true

julia> endswith(haystack, "Python")
false

Για να πάρεις τις θέσεις αρχή:τέλος μιας υποσυμβολοσειράς, έχουμε αρκετές συναρτήσεις:

julia> findfirst(needle, haystack)
9:13

Για να αντικαταστήσεις υποσυμβολοσειρές, απαρίθμησε τις αλλαγές χρησιμοποιώντας τη σύνταξη x => y.

julia> replace("abc", "a"=>"b", "b"=>"c", "c"=>"a")
"bca"

Από τη Julia 1.7, η συνάρτηση replace μπορεί να δεχτεί αυθαίρετο αριθμό αλλαγών, με την εγγύηση ότι κανένας χαρακτήρας δεν θα αλλαχτεί πάνω από μία φορά κατά την αντικατάσταση.

Η σύνταξη x => y ονομάζεται pair, ένας σημαντικός τύπος στη Julia που καλύπτεται με περισσότερες λεπτομέρειες στην έννοια Dicts and Pairs.

Σημείωση: Για απλότητα, όλα τα παραπάνω παραδείγματα χρησιμοποιούν κυριολεκτικές συμβολοσειρές. Πολλές από τις συναρτήσεις είναι γενικότερες, και θα δουλέψουν επίσης με κανονικές εκφράσεις. Θα επιστρέψουμε σε αυτό σε μια επόμενη έννοια.

Κενά διαστήματα

Συχνά χρειάζεται να αφαιρέσουμε τα κενά στην αρχή ή/και στο τέλος μιας συμβολοσειράς.

Οι συναρτήσεις για αυτό είναι οι lstrip() (αριστερά), rstrip() (δεξιά), strip() (και τα δύο).

julia> strip("\n\t  useful_bit\n\n")
"useful_bit"

Αλλαγή πεζών/κεφαλαίων

Αυτές οι συναρτήσεις έχουν αρκετά αυτονόητα ονόματα:

julia> s = repeat("aBcD ", 5)
"aBcD aBcD aBcD aBcD aBcD "

julia> uppercase(s)
"ABCD ABCD ABCD ABCD ABCD "

julia> lowercase(s)
"abcd abcd abcd abcd abcd "

julia> titlecase(s)  # Initial letter of each word uppercase
"Abcd Abcd Abcd Abcd Abcd "

Ανάλυση

Η αλληλομετατροπή αριθμών και της αναπαράστασής τους ως συμβολοσειρά είναι συχνά χρήσιμη.

Ο αριθμός σε συμβολοσειρά είναι απλός, αν και μια βάση διαφορετική από την προεπιλεγμένη 10 χρειάζεται μια επιπλέον παράμετρο:

julia> string(42)
"42"

julia> string(42, base=16)
"2a"

julia> string(42, base=2)
"101010"

Η ανάλυση μιας συμβολοσειράς για να πάρεις μια αριθμητική τιμή είναι λίγο πιο περίπλοκη, με περισσότερες πιθανότητες λάθους. Ο καθορισμός του ζητούμενου αριθμητικού τύπου είναι υποχρεωτικός. Ο καθορισμός της βάσης είναι προαιρετικός και έχει ως προεπιλογή το 10.

julia> parse(Int, "42")
42

julia> parse(Float64, "42")
42.0

julia> parse(Int, "42?")
ERROR: ArgumentError: invalid base 10 digit '?' in "42?"

julia> parse(Int, "42 ")  # whitespace may be tolerated
42

Ειδικές συμβολοσειρές

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

julia> x = 10
10

julia> "x = $x if we use \$ for interpolation"
"x = 10 if we use \$ for interpolation"

julia> raw"x = $x if we use \$ for interpolation"
"x = \$x if we use \\\$ for interpolation"

Οι κανονικές εκφράσεις έχουν τη δική τους περίπλοκη σύνταξη, και η Julia παρέχει δύο χρήσιμους τύπους συμβολοσειρών: το r" " για το Regex και το s" " για εργασία με τα τμήματα που συλλαμβάνονται.

Διάφορες άλλες ειδικές συμβολοσειρές είναι λιγότερο συχνές στον προγραμματισμό στυλ Exercism, αν και χρησιμοποιούνται ευρέως στη δημιουργία βιβλιοθηκών.

  • Οι συμβολοσειρές σημασιολογικής έκδοσης v"x.y.z" χειρίζονται την αρίθμηση major.minor.patch για τις κυκλοφορίες λογισμικού.
  • Τα κυριολεκτικά πίνακα byte b" " παρακάμπτουν τα όρια χαρακτήρων Unicode και λειτουργούν σε επίπεδο byte.
Επεξεργασία μέσω GitHub Ο σύνδεσμος ανοίγει σε νέο παράθυρο ή καρτέλα

Μάθε την έννοια Συμβολοσειρές

Η εξάσκηση είναι κλειδωμένη

Ξεκλείδωσε 2 ακόμη ασκήσεις για να εξασκηθείς στην έννοια Συμβολοσειρές