Διαδρομές
/
Julia
Julia
/
Ασκήσεις
/
Κανονικό chatbot
Κανονικό chatbot

Κανονικό chatbot

Άσκηση εκμάθησης

Εισαγωγή

Οι κανονικές εκφράσεις είναι ένας εξαιρετικά ευέλικτος τρόπος για την αντιστοίχιση μοτίβων σε συμβολοσειρές, χρησιμοποιώντας μια Γλώσσα Ειδικού Σκοπού (DSL) σχεδιασμένη γι' αυτόν τον σκοπό.

Όπως πολλές άλλες γλώσσες προγραμματισμού, η Julia δεν επιχειρεί να υλοποιήσει τη δική της βιβλιοθήκη Regex. Αντ' αυτού, τυλίγει τη δημοφιλή βιβλιοθήκη PCRE2, παρέχοντας έτσι σύνταξη κανονικών εκφράσεων ίδια με (για παράδειγμα) τη Gleam, και πολύ παρόμοια με τη Javascript.

Note

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

Παρακάτω παρατίθενται μερικές πηγές για να ανανεώσεις τις γνώσεις σου στις κανονικές εκφράσεις.

Η διεπαφή της Julia με τις κανονικές εκφράσεις περιγράφεται στο εγχειρίδιο.

Μια κανονική έκφραση στη Julia είναι απλώς μια συμβολοσειρά που έχει το πρόθεμα r πριν από το άνοιγμα ". Όλη η βασική λειτουργικότητα είναι μέρος της βασικής βιβλιοθήκης.

Στην πραγματικότητα, πολλές από τις συναρτήσεις που έχουμε ήδη συζητήσει στην έννοια Strings είναι σχεδιασμένες εξ ορισμού για αναζητήσεις με κανονικές εκφράσεις, όπως η occursin().

julia> re = r"test$"
r"test$"

julia> typeof(re)
Regex

# Does a string end with "test"?
julia> occursin(re, "this is a test")
true

julia> occursin(re, "these are tests")
false

Χαρακτήρες τροποποίησης μπορούν να ακολουθήσουν το κλείσιμο των εισαγωγικών, όπως το i για αντιστοίχιση χωρίς διάκριση πεζών-κεφαλαίων.

julia> occursin(r"test", "Testing")
false

julia> occursin(r"test"i, "Testing")
true

Ομάδες σύλληψης

Συχνά, θέλουμε να μάθουμε τι αντιστοιχίζεται. Αυτό επιτυγχάνεται με το να συμπεριλάβουμε ομάδες σύλληψης σε παρενθέσεις μέσα στην κανονική έκφραση και στη συνέχεια να χρησιμοποιήσουμε τη συνάρτηση match().

julia> m = match(r"(\d+g) .* (\d+ml)", "dissolve 25g sugar in 200ml water")
RegexMatch("25g sugar in 200ml", 1="25g", 2="200ml")

julia> m.captures
2-element Vector{Union{Nothing, SubString{String}}}:
 "25g"
 "200ml"

# how many matches?
julia> length(m.captures)
2

# what matched?
julia> m[1], m[2]
("25g", "200ml")

# Starting positions of the matches (character index)
julia> m.offsets
2-element Vector{Int64}:
 10
 23

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

# failed match
m = match(r"(not here)", "dissolve 25g sugar in 200ml water")

julia> typeof(m)
Nothing

julia> isnothing(m)
true

Αν και η match ξεκινά από προεπιλογή από την αρχή της συμβολοσειράς, μπορούμε επίσης να ορίσουμε μια μετατόπιση n ώστε να αγνοήσουμε τους πρώτους n χαρακτήρες.

# capture first match
julia> m = match(r"(\wat)", "cat, sat, mat")
RegexMatch("cat", 1="cat")

# ignore first 5 characters, then match
julia> m = match(r"(\wat)", "cat, sat, mat", 5)
RegexMatch("sat", 1="sat")

Στη Julia, η match() θα βρει μόνο την πρώτη αντιστοίχιση μέσα στη συμβολοσειρά-στόχο: δεν υπάρχει καθολικός τροποποιητής όπως σε κάποιες άλλες γλώσσες.

Αντ' αυτού, έχουμε την eachmatch(), η οποία επιστρέφει έναν επαναλήπτη αντιστοιχίσεων. Αυτός αξιολογείται οκνηρά, οπότε μπορεί να χρειαστεί να τον μετατρέψεις στη μορφή που θέλεις.

julia> matches = eachmatch(r"(\wat)", "cat, sat, mat")
Base.RegexMatchIterator{String}(r"(\wat)", "cat, sat, mat", false)

# convert to vector
julia> collect(matches)
3-element Vector{RegexMatch}:
 RegexMatch("cat", 1="cat")
 RegexMatch("sat", 1="sat")
 RegexMatch("mat", 1="mat")

# convert with comprehension
julia> [m.match for m in matches]
3-element Vector{SubString{String}}:
 "cat"
 "sat"
 "mat"

# broadcast an anonymous function
julia> (m -> m.match).(matches)
3-element Vector{SubString{String}}:
 "cat"
 "sat"
 "mat"

Αντικατάσταση

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

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

julia> replace("some string", r"[aeiou]" => "*")
"s*m* str*ng"

julia> replace("first second", r"(\w+) (?<agroup>\w+)" => s"\g<agroup> \1")
"second first"

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

Δες το εγχειρίδιο για περισσότερες λεπτομέρειες: αυτό είναι ένα θέμα που αναγκάζει συνεχώς τους περισσότερους προγραμματιστές να επιστρέφουν στην τεκμηρίωση!

Οδηγίες

Έχεις προσληφθεί ως ειδικός κανονικών εκφράσεων σε μια εταιρεία που αναπτύσσει ένα chatbot.

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

Note

Για εκπαιδευτικούς σκοπούς, λύσε αυτές τις εργασίες χρησιμοποιώντας κανονικές εκφράσεις.

Ξέρουμε ότι μερικές φορές υπάρχουν εναλλακτικές λύσεις (που μπορεί να είναι και πιο αποδοτικές!)

1. Έλεγχος έγκυρης εντολής

Εκτός από έξυπνο, το chatbot είναι και πιστός βοηθός.

Για να ζητήσει κάτι από το chatbot, ο χρήστης πρέπει να πει τη λέξη "Chatbot" στην πρώτη θέση της εντολής.

Δεν έχει σημασία αν η λέξη-κλειδί είναι σε ΚΕΦΑΛΑΙΑ ή πεζά. Το σημαντικό εδώ είναι η θέση της λέξης.

Υλοποίησε τη συνάρτηση is_valid_command() που βοηθά το chatbot να αναγνωρίζει πότε ο χρήστης δίνει μια εντολή.

julia> is_valid_command("Chatbot, play a song from the 80's.")
True

julia> is_valid_command("Hey Chatbot, where is the closest pharmacy?")
False

julia> is_valid_command("CHATBOT, do you have a solution for this challenge?")
True

2. Αφαίρεση κρυπτογραφημένων emoji

Το chatbot δυσκολεύεται να καταλάβει πώς οι άνθρωποι χρησιμοποιούν τα emoji για να εκφράσουν τα συναισθήματά τους.

Όταν το chatbot λαμβάνει μηνύματα από τον χρήστη, κάθε emoji αναπαρίσταται ως "emoji" ακολουθούμενο από τον αριθμό id του.

Υλοποίησε τη μέθοδο remove_emoji() που παίρνει μια συμβολοσειρά και αφαιρεί όλη την κρυπτογράφηση των emoji σε όλο το μήνυμα.

Οι γραμμές που δεν περιέχουν κείμενο emoji πρέπει να επιστρέφονται αμετάβλητες.

Απλώς αφαίρεσε τη συμβολοσειρά του emoji. Μην επιχειρήσεις να προσαρμόσεις τα κενά.

julia> remove_emoji("I love playing videogames emoji3465 it's one of my hobbies")
"I love playing videogames  it's one of my hobbies"

3. Έλεγχος έγκυρου αριθμού τηλεφώνου

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

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

Αν ο αριθμός είναι έγκυρος (ταιριάζει με την ακολουθία χαρακτήρων που ορίζει η κανονική έκφραση), το chatbot απαντά με ένα μήνυμα που ευχαριστεί τον χρήστη και επιβεβαιώνει τον αριθμό. Αν ο αριθμός δεν είναι έγκυρος, η συνάρτηση ενημερώνει τον χρήστη ότι ο αριθμός τηλεφώνου δεν είναι έγκυρος.

Η αναμενόμενη μορφή είναι: (+##) ###-###-###

julia> check_phone_number("(+34) 659-771-594")
"Thanks! You can now download me to your phone."

julia> check_phone_number("659-771-594")
"Oops, it seems like I can't reach out to 659-771-594"

4. Ανάκτηση συνδέσμου ιστοσελίδας

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

Παράδειγμα συνομιλίας:

  • Chatbot: Γεια σου username, θα ήθελα να μάθω προγραμματισμό σε JavaScript, ξέρεις καμία ωραία ιστοσελίδα όπου θα μπορούσα να μάθω;
  • User: Έμαθα πολλά από το exercism.org

Υλοποίησε τη συνάρτηση getURL() που μπορεί να επιστρέψει έναν πίνακα με μόνο τον σύνδεσμο κάθε ιστοσελίδας.

julia> getURL("I learned a lot from exercism.org")
["exercism.org"]

5. Χαιρετισμός του χρήστη

Για να αποθηκεύει δεδομένα από όλα τα άτομα με τα οποία έχει συνομιλήσει, το chatbot μπορεί να πάρει το πλήρες όνομα από το προφίλ του χρήστη με αυτή τη μορφή: "smith, john".

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

Γράψε τη συνάρτηση nice_to_meet_you() που παίρνει μια συμβολοσειρά με το πλήρες όνομα του χρήστη και επιστρέφει τη συμβολοσειρά "Nice to meet you, John Smith"

julia> str = "Smith, John"

julia> nice_to_meet_you(str)
"Nice to meet you, John Smith"
Επεξεργασία μέσω GitHub Ο σύνδεσμος ανοίγει σε νέο παράθυρο ή καρτέλα
Julia Exercism

Έτοιμος να ξεκινήσεις την άσκηση Κανονικό chatbot;

Γράψου στο Exercism για να μάθεις και να κατακτήσεις Julia με 35 έννοιες128 ασκήσεις και πραγματική καθοδήγηση από ανθρώπους, όλα δωρεάν.