Διαδρομές
/
Go
Go
/
Ύλη
/
Κανονικές εκφράσεις
Κα

Κανονικές εκφράσεις σε Go

1 άσκηση

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

Το πακέτο regexp προσφέρει υποστήριξη για κανονικές εκφράσεις στη Go.

Σύνταξη

Η σύνταξη των κανονικών εκφράσεων που γίνονται δεκτές είναι η ίδια γενική σύνταξη που χρησιμοποιούν η Perl, η Python και άλλες γλώσσες.

Τόσο τα μοτίβα αναζήτησης όσο και τα κείμενα εισόδου ερμηνεύονται ως UTF-8.

Όταν χρησιμοποιείς backticks (βαρείες) για να φτιάξεις συμβολοσειρές, οι ανάστροφες κάθετοι () to make strings, backslashes () δεν έχουν κανένα ιδιαίτερο νόημα και δεν σηματοδοτούν την αρχή ειδικών χαρακτήρων όπως το tab ) don't have any special meaning and don't mark the beginning of special characters like tabs ή η αλλαγή γραμμής or newlines:

"\t\n" // regular string literal with 2 characters: a tab and a newline
`\t\n`// raw string literal with 4 characters: two backslashes, a 't', and an 'n'

Εξαιτίας αυτού, είναι προτιμότερο να χρησιμοποιείς backticks για να φτιάχνεις κανονικές εκφράσεις, γιατί έτσι δεν χρειάζεται να κάνεις escape τις ανάστροφες κάθετους:

"\\" // string with a single backslash
`\\` // string with 2 backslashes

Μεταγλώττιση μοτίβων - τύπος RegExp

Για να χρησιμοποιήσουμε μια κανονική έκφραση, πρέπει πρώτα να μεταγλωττίσουμε το μοτίβο της συμβολοσειράς. Η μεταγλώττιση εδώ σημαίνει ότι παίρνουμε το μοτίβο της συμβολοσειράς της κανονικής έκφρασης και το μετατρέπουμε σε μια εσωτερική αναπαράσταση με την οποία είναι πιο εύκολο να δουλέψουμε. Χρειάζεται να μεταγλωττίσουμε κάθε μοτίβο μόνο μία φορά, μετά μπορούμε να χρησιμοποιήσουμε τη μεταγλωττισμένη εκδοχή της κανονικής έκφρασης πολλές φορές. Ο τύπος regexp.Regexp αναπαριστά μια μεταγλωττισμένη κανονική έκφραση. Μπορούμε να μεταγλωττίσουμε ένα μοτίβο συμβολοσειράς σε ένα regexp.Regexp χρησιμοποιώντας τη συνάρτηση regexp.Compile. Αυτή η συνάρτηση επιστρέφει nil και ένα σφάλμα αν η μεταγλώττιση αποτύχει:

re, err := regexp.Compile(`(a|b)+`)
fmt.Println(re, err) // => (a|b)+ <nil>
re, err = regexp.Compile(`a|b)+`)
fmt.Println(re, err) // => <nil> error parsing regexp: unexpected ): `a|b)+`

Η συνάρτηση MustCompile είναι μια βολική εναλλακτική στη Compile:

re = regexp.MustCompile(`[a-z]+\d*`)

Χρησιμοποιώντας αυτή τη συνάρτηση, δεν χρειάζεται να χειριστείς κάποιο σφάλμα.

Caution

Το MustCompile θα πρέπει να χρησιμοποιείται μόνο όταν ξέρουμε με βεβαιότητα ότι το μοτίβο μεταγλωττίζεται, γιατί αλλιώς το πρόγραμμα θα προκαλέσει panic.

Μέθοδοι κανονικών εκφράσεων

Υπάρχουν 16 μέθοδοι του Regexp που ταιριάζουν μια κανονική έκφραση και εντοπίζουν το κείμενο που ταιριάζει. Τα ονόματά τους ταιριάζουν με αυτή την κανονική έκφραση:

Find(All)?(String)?(Submatch)?(Index)?
  • Αν υπάρχει το All, η ρουτίνα βρίσκει διαδοχικά, μη επικαλυπτόμενα ταιριάσματα ολόκληρης της έκφρασης.
  • Αν υπάρχει το String, το όρισμα είναι συμβολοσειρά· αλλιώς είναι ένα slice από bytes· οι τιμές επιστροφής προσαρμόζονται ανάλογα.
  • Αν υπάρχει το Submatch, η τιμή επιστροφής είναι ένα slice που προσδιορίζει τα διαδοχικά υποταιριάσματα της έκφρασης.
  • Αν υπάρχει το Index, τα ταιριάσματα και τα υποταιριάσματα προσδιορίζονται από ζεύγη θέσεων byte μέσα στη συμβολοσειρά εισόδου.

Υπάρχουν επίσης μέθοδοι για:

  • την αντικατάσταση ταιριασμάτων κανονικών εκφράσεων με συμβολοσειρές αντικατάστασης και
  • τον διαχωρισμό συμβολοσειρών που χωρίζονται από κανονικές εκφράσεις.

Συνολικά, το πακέτο regexp ορίζει περισσότερες από 40 συναρτήσεις και μεθόδους. Θα δείξουμε τη χρήση μερικών μεθόδων παρακάτω. Δες την τεκμηρίωση του API για λεπτομέρειες σχετικά με αυτές και άλλες συναρτήσεις.

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

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

re = regexp.MustCompile(`[a-z]+\d*`)
b = re.MatchString("[a12]")       // => true
b = re.MatchString("12abc34(ef)") // => true
b = re.MatchString(" abc!")       // => true
b = re.MatchString("123 456")     // => false

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

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

re = regexp.MustCompile(`[a-z]+\d*`)
s = re.FindString("[a12]")       // => "a12"
s = re.FindString("12abc34(ef)") // => "abc34"
s = re.FindString(" abc!")       // => "abc"
s = re.FindString("123 456")     // => ""

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

Η μέθοδος FindStringSubmatch επιστρέφει ένα slice από συμβολοσειρές που περιέχει το κείμενο του αριστερότερου ταιριάσματος της κανονικής έκφρασης και τα ταιριάσματα, αν υπάρχουν, των υποεκφράσεών της. Αυτό μπορεί να χρησιμοποιηθεί για να προσδιορίσεις τις συμβολοσειρές που ταιριάζουν με ομάδες σύλληψης. Μια τιμή επιστροφής nil δηλώνει ότι δεν υπάρχει ταίριασμα.

re = regexp.MustCompile(`[a-z]+(\d*)`)
sl = re.FindStringSubmatch("[a12]")       // => []string{"a12","12"}
sl = re.FindStringSubmatch("12abc34(ef)") // => []string{"abc34","34"}
sl = re.FindStringSubmatch(" abc!")       // => []string{"abc",""}
sl = re.FindStringSubmatch("123 456")     // => <nil>

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

Η μέθοδος re.ReplaceAllString(src,repl) επιστρέφει ένα αντίγραφο του src, αντικαθιστώντας τα ταιριάσματα της κανονικής έκφρασης re με τη συμβολοσειρά αντικατάστασης repl.

re = regexp.MustCompile(`[a-z]+\d*`)
s = re.ReplaceAllString("[a12]", "X")       // => "[X]"
s = re.ReplaceAllString("12abc34(ef)", "X") // => "12X(X)"
s = re.ReplaceAllString(" abc!", "X")       // => " X!"
s = re.ReplaceAllString("123 456", "X")     // => "123 456"

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

Η μέθοδος re.Split(s,n) κόβει ένα κείμενο s σε υποσυμβολοσειρές που χωρίζονται από την έκφραση και επιστρέφει ένα slice με τις υποσυμβολοσειρές ανάμεσα σε αυτά τα ταιριάσματα της έκφρασης. Το πλήθος n καθορίζει τον μέγιστο αριθμό υποσυμβολοσειρών που θα επιστραφούν. Αν n<0, η μέθοδος επιστρέφει όλες τις υποσυμβολοσειρές.

re = regexp.MustCompile(`[a-z]+\d*`)
sl = re.Split("[a12]", -1)      // => []string{"[","]"}
sl = re.Split("12abc34(ef)", 2) // => []string{"12","(ef)"}
sl = re.Split(" abc!", -1)      // => []string{" ","!"}
sl = re.Split("123 456", -1)    // => []string{"123 456"}

Απόδοση

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

Επιφύλαξη

Το πακέτο regexp υλοποιεί τις κανονικές εκφράσεις RE2 (εκτός από το \C). Η σύνταξη είναι σε μεγάλο βαθμό συμβατή με PCRE ("Perl Compatible Regular Expression"), αλλά υπάρχουν κάποιες διαφορές. Δες την ενότητα "Caveat" σε αυτό το άρθρο για λεπτομέρειες.

Επεξεργασία μέσω GitHub Ο σύνδεσμος ανοίγει σε νέο παράθυρο ή καρτέλα

Μάθε την έννοια Κανονικές εκφράσεις

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

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