MySQL Κανονικές εκφράσεις (Regexp)

⚡ Έξυπνη Σύνοψη

MySQL Οι Κανονικές Εκφράσεις (REGEXP) αντιστοιχίζουν τιμές στηλών με ευέλικτα μοτίβα που δεν μπορούν να εκφράσουν οι χαρακτήρες μπαλαντέρ. Αυτό εξηγεί τη σύνταξη REGEXP, το συνώνυμο RLIKE, κάθε υποστηριζόμενο μεταχαρακτήρα, διορθωμένα παραδείγματα ερωτημάτων σε σχέση με τη βάση δεδομένων myflixdb και τις συναρτήσεις κανονικών εκφράσεων που προστέθηκαν στο MySQL 8.0.

  • 🔍 πυρήνας Operaβραχώδης κορυφή: Η συνάρτηση REGEXP συγκρίνει μια στήλη με ένα μοτίβο και επιστρέφει 1 για αντιστοίχιση, ενώ η συνάρτηση RLIKE είναι ακριβές συνώνυμο της συνάρτησης REGEXP.
  • 🧩 πρότυπο Anchors: Ο κέρσορας (^) αγκυρώνει την αντιστοίχιση στην αρχή της τιμής και το σύμβολο του δολαρίου ($) την αγκυρώνει στο τέλος.
  • 🔤 Λίστες χαρακτήρων: Το [abcd] αντιστοιχεί σε οποιονδήποτε περικλειόμενο χαρακτήρα και το [^abcd] εξαιρεί κάθε περικλειόμενο χαρακτήρα από το σύνολο αποτελεσμάτων.
  • Ποσοδείκτες: Ο αστερίσκος, το σύμβολο συν και το ερωτηματικό ισχύουν για τον μοναδικό χαρακτήρα που προηγείται αυτών και όχι για ολόκληρη τη συμβολοσειρά.
  • Escaping Κανόνας: Μια κυριολεκτική ανάστροφη κάθετος πρέπει να διπλασιαστεί μέσα σε ένα μοτίβο, επειδή MySQL επεξεργάζεται τη συμβολοσειρά δύο φορές.
  • 🆕 Αλλαγή έκδοσης: MySQL Η έκδοση 8.0 μεταφέρθηκε στη μηχανή ICU, αντικατέστησε τα [[:<:]] και [[:>:]] με \b και πρόσθεσε τα REGEXP_LIKE, REGEXP_REPLACE, REGEXP_SUBSTR και REGEXP_INSTR.
  • Σημείωση απόδοσης: Το REGEXP δεν χρησιμοποιεί ποτέ ευρετήριο, επομένως φιλτράρετε πρώτα τις γραμμές με μια συνθήκη με ευρετήριο όποτε το επιτρέπει το ερώτημα.

Τι είναι MySQL κανονικές εκφράσεις;

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

Αν έχετε ήδη συνεργαστεί με MySQL wildcards, μπορεί να αναρωτηθείτε γιατί αξίζει να μαθαίνουμε κανονικές εκφράσεις όταν το LIKE παράγει παρόμοια αποτελέσματα. Η απάντηση είναι η εκφραστική δύναμη: οι χαρακτήρες μπαλαντέρ προσφέρουν μόνο δύο σύμβολα, ενώ οι κανονικές εκφράσεις περιγράφουν εύρη χαρακτήρων, εναλλακτικές λύσεις, επανάληψη και θέσεις λέξεων σε ένα μόνο μοτίβο.

Έχοντας καθορίσει τον σκοπό, η επόμενη ενότητα παρουσιάζει τη σύνταξη που θα χρησιμοποιείτε σε κάθε ερώτημα REGEXP.

Βασική σύνταξη του REGEXP

Η βασική σύνταξη για μια κανονική έκφραση έχει ως εξής.

SELECT * FROM table_name
WHERE fieldname REGEXP 'pattern';

ΕΔΩ:

  • «Δήλωση SELECT» είναι το πρότυπο Δήλωση SELECT.
  • "WHERE όνομα πεδίου" είναι το όνομα της στήλης στην οποία εκτελείται η κανονική έκφραση.
  • “Μοτίβο REGEXP” — Το REGEXP είναι ο τελεστής κανονικής έκφρασης και το «pattern» αντιπροσωπεύει το μοτίβο που θα αντιστοιχιστεί. RLIKE είναι ένα συνώνυμο του REGEXP και επιστρέφει τα ίδια αποτελέσματα. Για να μην το συγχέετε με τον τελεστή LIKE, είναι καλύτερο να χρησιμοποιήσετε REGEXP.

Ας δούμε τώρα ένα πρακτικό παράδειγμα.

SELECT * FROM `movies`
WHERE `title` REGEXP 'code';

Το παραπάνω ερώτημα αναζητά όλους τους τίτλους ταινιών που περιέχουν τη λέξη «code». Δεν έχει σημασία αν η λέξη «code» εμφανίζεται στην αρχή, στη μέση ή στο τέλος του τίτλου. Εφόσον ο τίτλος περιέχει το μοτίβο, επιστρέφεται η γραμμή.

Αντιστοίχιση της αρχής μιας τιμής με μια λίστα χαρακτήρων

Ας υποθέσουμε ότι θέλουμε τις ταινίες των οποίων οι τίτλοι ξεκινούν με a, b, c ή d, ακολουθούμενες από οποιονδήποτε αριθμό άλλων χαρακτήρων. Συνδυάζουμε μια λίστα χαρακτήρων με τον μεταχαρακτήρα caret για να επιτύχουμε αυτό το αποτέλεσμα.

SELECT * FROM `movies`
WHERE `title` REGEXP '^[abcd]';

Εκτέλεση του παραπάνω σεναρίου στο MySQL Πάγκος εργασίας σε σχέση με τη βάση δεδομένων myflixdb μας δίνει τα ακόλουθα αποτελέσματα.

movie_id τίτλος διευθυντής έτος_κυκλοφόρησε κατηγορία_αναγνωριστικό
4 Code Όνομα Μαύρο Έντγκαρ Τζιμς 2010 Τιμή NULL
5 Μικρά κορίτσια του μπαμπά Τιμή NULL 2007 8
6 Αγγελοι και ΔΑΙΜΟΝΕΣ Τιμή NULL 2007 6
7 Ντα Βίντσι Code Τιμή NULL 2007 6

Στο μοτίβο '^[abcd]', ο κέρσορας (^) απαιτεί η αντιστοίχιση να ξεκινά στην αρχή της τιμής και η λίστα χαρακτήρων [abcd] δέχεται μόνο τίτλους των οποίων το πρώτο γράμμα είναι a, b, c ή d. Η σύγκριση δεν κάνει διάκριση πεζών-κεφαλαίων στην προεπιλεγμένη ταξινόμηση, γι' αυτό και "Code Επιστρέφεται το "Όνομα Μαύρο".

Εξαίρεση χαρακτήρων με λίστα αρνητικών χαρακτήρων

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

SELECT * FROM `movies`
WHERE `title` REGEXP '^[^abcd]';

Εκτέλεση του παραπάνω σεναρίου στο MySQL Το Workbench σε σχέση με τη βάση δεδομένων myflixdb μας δίνει τα ακόλουθα αποτελέσματα.

movie_id τίτλος διευθυντής έτος_κυκλοφόρησε κατηγορία_αναγνωριστικό
1 Πειρατές της Καραϊβικής 4 Ρομπ Μάρσαλ 2011 1
2 Ξεχνώντας τη Σάρα Μάρσαλ Nicholas Stoller 2008 2
3 X Men 2008
9 Honey mooners Τζον Σουλτς 2005 8
16 67% Ένοχοι 2012
17 Ο Μεγάλος Δικτάτορας Τσάλι Τσάπλι 1920 7
18 δείγμα ταινίας ανώνυμος 8
19 ταινία 3 John Brown 1920 8

Μέσα σε μια λίστα χαρακτήρων, το σύμβολο caret αλλάζει νόημα: Το '^[^abcd]' εξακολουθεί να αγκυρώνει την αντιστοίχιση στην αρχή, ενώ το [^abcd] εξαιρεί πλέον κάθε τίτλο που ξεκινά με έναν από τους συνημμένους χαρακτήρες.

Αυτά τα δύο παραδείγματα χρησιμοποιούν μόνο άγκυρες και λίστες χαρακτήρων. Η επόμενη ενότητα καλύπτει το πλήρες σύνολο μεταχαρακτήρων.

Μεταχαρακτήρες κανονικής έκφρασης

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

Char Περιγραφή Παράδειγμα
* The αστερίσκος (*) αντιστοιχεί σε μηδέν (0) ή περισσότερες περιπτώσεις του ένας χαρακτήρας που προηγείται αυτού. ΕΠΙΛΟΓΗ * ΑΠΟ ταινίες ΟΠΟΥ ο τίτλος REGEXP 'da*'; ταιριάζει με ένα «d» ακολουθούμενο από μηδέν ή περισσότερους χαρακτήρες «a», άρα ο Da Vinci Code και τα Daddy's Little Girls πληρούν τις προϋποθέσεις. Χρησιμοποιήστε το 'da+' όταν πρέπει να υπάρχει το γράμμα «a».
+ The συν (+) ταιριάζει με μία ή περισσότερες εμφανίσεις του χαρακτήρα που προηγείται αυτού. ΕΠΙΛΕΞΤΕ * ΑΠΟ «ταινίες» ΟΠΟΥ «τίτλος» REGEXP «μον+»; δίνει όλες τις ταινίες που περιέχουν το γράμμα «mon» ακολουθούμενο από έναν ή περισσότερους χαρακτήρες «n». Για παράδειγμα, Άγγελοι και Δαίμονες.
? The ερωτηματικό (?) αντιστοιχεί σε μηδέν (0) ή σε μία παρουσία του χαρακτήρα που προηγείται αυτού. SELECT * FROM `categories` WHERE `category_name` REGEXP 'com?'; ταιριάζει με το «co» με ένα προαιρετικό «m». Για παράδειγμα, κωμωδία και ρομαντική κωμωδία.
. The τελεία (.) ταιριάζει με οποιονδήποτε μεμονωμένο χαρακτήρα εκτός από μια νέα γραμμή. ΕΠΙΛΟΓΗ * ΑΠΟ ταινίες WHERE `year_released` REGEXP '200.'; Δίνει όλες τις ταινίες που κυκλοφόρησαν σε ένα έτος ξεκινώντας με «200» ακολουθούμενη από οποιονδήποτε μεμονωμένο χαρακτήρα. Για παράδειγμα, 2005, 2007, 2008.
[αλφάβητο] The λίστα χαρακτήρων [abc] ταιριάζει με οποιονδήποτε από τους συνημμένους χαρακτήρες. ΕΠΙΛΟΓΗ * ΑΠΟ "ταινίες" ΟΠΟΥ "τίτλος" REGEXP "[vwxyz]"; εμφανίζει όλες τις ταινίες που περιέχουν οποιονδήποτε χαρακτήρα από το "vwxyz". Για παράδειγμα, X-Men και Da Vinci Code.
[^ abc] The λίστα αρνητικών στοιχείων [^abc] ταιριάζει με οποιονδήποτε χαρακτήρα εκτός από αυτούς που περιλαμβάνονται. SELECT * FROM `movies` WHERE `title` REGEXP '^[^vwxyz]'; δίνει όλες τις ταινίες των οποίων ο τίτλος δεν ξεκινά με έναν χαρακτήρα στο "vwxyz".
[ΑΖ] The εύρος [AZ] ταιριάζει με οποιοδήποτε κεφαλαίο γράμμα. SELECT * FROM `members` WHERE `postal_address` REGEXP '[AZ]'; δίνει όλα τα μέλη των οποίων η ταχυδρομική διεύθυνση περιέχει ένα γράμμα μεταξύ του Α και του Ω. Για παράδειγμα, η Janet Jones με αριθμό μέλους 1.
[αζ] The εύρος [az] ταιριάζει με οποιοδήποτε μικρό γράμμα. SELECT * FROM `members` WHERE `postal_address` REGEXP '[az]'; δίνει σε όλα τα μέλη των οποίων η ταχυδρομική διεύθυνση περιέχει ένα γράμμα μεταξύ a και z. Σημειώστε ότι η προεπιλεγμένη ταξινόμηση δεν κάνει διάκριση πεζών-κεφαλαίων, επομένως αυτό το εύρος ταιριάζει επίσης με κεφαλαία γράμματα.
[0-9] The εύρος [0-9] ταιριάζει με οποιοδήποτε ψηφίο από το 0 έως το 9. SELECT * FROM `μέλη` WHERE `αριθμός_επαφής` REGEXP '[0-9]'; δίνει όλα τα μέλη των οποίων ο αριθμός τηλεφώνου περιέχει τουλάχιστον ένα ψηφίο. Για παράδειγμα, Robert Phil.
^ The καρέ (^) αγκυρώνει την αντιστοίχιση στην αρχή της τιμής. SELECT * FROM `movies` WHERE `title` REGEXP '^[cd]'; δίνει όλες τις ταινίες των οποίων ο τίτλος αρχίζει με «c» ή «d». Για παράδειγμα, Code Όνομα Black, Daddy's Little Girls και Da Vinci Code.
$ The σύμβολο του δολαρίου ($) αγκυρώνει την αντιστοίχιση στο τέλος της τιμής. SELECT * FROM `ταινίες` WHERE `τίτλος` REGEXP 'κωδικός$'; δίνει όλες τις ταινίες των οποίων ο τίτλος τελειώνει με «κωδικός». Για παράδειγμα, Davinci Code.
| The κάθετη μπάρα (|) απομονώνει εναλλακτικές λύσεις. SELECT * FROM `movies` WHERE `title` REGEXP '^[cd]|^[u]'; δίνει όλες τις ταινίες των οποίων ο τίτλος αρχίζει με «c», «d» ή «u». Για παράδειγμα, Code Όνομα Black, Da Vinci Code, και Κάτω Κόσμος – AwakenING.
\b The όριο λέξης (\b) ταιριάζει με την αρχή ή το τέλος μιας λέξης. Αντικαθιστά τους παλαιότερους δείκτες [[:<:]] και [[:>:]], οι οποίοι MySQL Η έκδοση 8.0 αφαιρέθηκε. SELECT * FROM `ταινίες` WHERE `τίτλος` REGEXP '\\bfor'; δίνει όλες τις ταινίες με μια λέξη που αρχίζει με «για». Για παράδειγμα, Forgetting Sarah Marshal. Ενεργοποιημένο MySQL 5.7 το ισοδύναμο μοτίβο είναι '[[:<:]]for'.
[[:τάξη:]] The κλάση χαρακτήρων αντιστοιχεί σε μια ονομαστική ομάδα χαρακτήρων: [[:alpha:]] για γράμματα, [[:space:]] για κενό, [[:punct:]] για στίξη και [[:upper:]] για κεφαλαία γράμματα. Σημειώστε το διπλασιαστεί αγκύλες. SELECT * FROM `ταινίες` WHERE `τίτλος` REGEXP '^[[:alpha:][:space:]]+$'; Εμφανίζει όλες τις ταινίες των οποίων ο τίτλος περιέχει μόνο γράμματα και κενά. Για παράδειγμα, Forgetting Sarah Marshal, ενώ το Pirates of the Caribbean 4 παραλείπεται λόγω του ψηφίου.

Η ανάστροφη κάθετος (\) είναι ο χαρακτήρας διαφυγής. Επειδή MySQL αναλύει πρώτα τη συμβολοσειρά και στη συνέχεια το μοτίβο, μια κυριολεκτική ανάστροφη κάθετος πρέπει να γραφτεί ως διπλή ανάστροφη κάθετος (\\) μέσα σε ένα μοτίβο REGEXP.

⚠️ Προειδοποίηση έκδοσης: MySQL Η έκδοση 8.0.4 αντικατέστησε την παλιά μηχανή κανονικών εκφράσεων με τη βιβλιοθήκη ICU. Οι δείκτες λέξεων [[:<:]] και [[:>:]] αφαιρέθηκαν σε αυτήν την έκδοση, επομένως τα μοτίβα που αντιγράφηκαν από παλαιότερο υλικό αποτυγχάνουν με ένα "σφάλμα σύνταξης" στο MySQL 8.0. Χρησιμοποιήστε \b αντί αυτού.

Τώρα που κάθε μεταχαρακτήρας έχει οριστεί, προκύπτει ένα εύλογο ερώτημα: πότε θα πρέπει το REGEXP να αντικαταστήσει τον απλούστερο τελεστή LIKE;

REGEXP vs LIKE: ποιο πρέπει να χρησιμοποιήσετε;

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

Κριτήριο LIKE REGEXP
Σύμβολα μοτίβων % και _ μόνο Anchors, εύρη, εναλλαγή, ποσοδείκτες, κλάσεις χαρακτήρων
Τυπική χρήση Αναζητήσεις με πρόθεμα, επίθημα και «περιέχει» Επικύρωση, πολλαπλές εναλλακτικές λύσεις, αντιστοίχιση με επίγνωση θέσης
Χρήση ευρετηρίου Πιθανό όταν το μοτίβο δεν ξεκινά με % Δεν χρησιμοποιεί ποτέ ευρετήριο
Τιμή επιστροφής Σωστό ή λάθος 1 ή 0, και NULL όταν κάποιος τελεστής είναι NULL

Επιλέξτε LIKE για άμεση αντιστοίχιση, επειδή διαβάζεται καλά και μπορεί να χρησιμοποιήσει ένα ευρετήριο. Επιλέξτε REGEXP όταν ένα μόνο μοτίβο πρέπει να εκφράζει πολλούς κανόνες ταυτόχρονα, όπως "ξεκινά με c ή d και τελειώνει με ένα ψηφίο". Σε μεγάλους πίνακες, περιορίστε πρώτα τις γραμμές με μια συνθήκη με ευρετήριο και, στη συνέχεια, εφαρμόστε REGEXP σε αυτό το μικρότερο σύνολο.

MySQL 8.0 συναρτήσεις κανονικών εκφράσεων

Ο τελεστής REGEXP απαντά μόνο σε μία ερώτηση: ταιριάζει η τιμή με το μοτίβο; MySQL Η έκδοση 8.0 πρόσθεσε τέσσερις λειτουργίες που προχωρούν παραπέρα και σας επιτρέπουν να εντοπίζετε, π.χ.tract και ξαναγράψτε το αντίστοιχο κείμενο. Κάθε ένα δέχεται ένα προαιρετικό όρισμα match_type, όπου το 'c' επιβάλλει μια σύγκριση με διάκριση πεζών-κεφαλαίων και το 'i' επιβάλλει μια σύγκριση χωρίς διάκριση πεζών-κεφαλαίων.

  • REGEXP_LIKE(παράσταση, μοτίβο) Επιστρέφει 1 όταν η τιμή ταιριάζει με το μοτίβο. Είναι η μορφή συνάρτησης του τελεστή REGEXP και το όρισμα match_type καθιστά σαφή την ευαισθησία πεζών-κεφαλαίων.
  • REGEXP_INSTR(παράσταση, μοτίβο) επιστρέφει τη θέση του πρώτου χαρακτήρα της αντιστοίχισης ή 0 όταν δεν βρεθεί το μοτίβο.
  • REGEXP_SUBSTR(έκφραση, μοτίβο) επιστρέφει την ίδια την αντίστοιχη δευτερεύουσα συμβολοσειρά, η οποία είναι χρήσιμη για την εξαγωγή ενός έτους, ενός κωδικού ή ενός αριθμού από μια μεγαλύτερη τιμή κειμένου.
  • REGEXP_REPLACE(παράσταση, μοτίβο, αντικατάσταση) επιστρέφει την τιμή με κάθε αντιστοίχιση που αντικαθίσταται, ώστε να μπορεί να καθαρίσει δεδομένα μέσα σε ένα Ερώτημα SQL UPDATE.
SELECT title,
       REGEXP_SUBSTR(title, '[0-9]+') AS number_in_title
FROM `movies`
WHERE REGEXP_LIKE(title, '[0-9]');

Το παραπάνω ερώτημα επιστρέφει κάθε τίτλο ταινίας που περιέχει ένα ψηφίο, μαζί με τα ίδια τα ψηφία. MySQL 5.7 αυτές οι συναρτήσεις δεν είναι διαθέσιμες, επομένως ο τελεστής REGEXP παραμένει η μόνη επιλογή.

Συχνές Ερωτήσεις

Όχι από προεπιλογή. Η συνάρτηση REGEXP ακολουθεί τη συρραφή της στήλης και οι τυπικές συρραφές δεν κάνουν διάκριση πεζών-κεφαλαίων. Προσθέστε τη λέξη-κλειδί BINARY πριν από τη στήλη ή καλέστε τη συνάρτηση REGEXP_LIKE με τον τύπο αντιστοίχισης 'c', για να επιβάλετε μια σύγκριση με διάκριση πεζών-κεφαλαίων.

Δεν υπάρχει λειτουργική διαφορά. Το RLIKE είναι συνώνυμο του REGEXP που MySQL διατηρείται για λόγους συμβατότητας. Το REGEXP προτιμάται στην πράξη, επειδή το RLIKE συγχέεται εύκολα με το άσχετο Τελεστής LIKE χρησιμοποιείται για μπαλαντέρ.

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

Ναι. Οι βοηθοί τεχνητής νοημοσύνης μετατρέπουν έναν κανόνα απλής γλώσσας σε ένα μοτίβο REGEXP και εξηγούν κάθε μεταχαρακτήρα. Δοκιμάστε το αποτέλεσμα σε MySQL Πάγκος εργασίας σε σχέση με τις σειρές δειγμάτων, επειδή μια μεμονωμένη λανθασμένη αγκύρωση αλλάζει ολόκληρο το σύνολο αποτελεσμάτων.

Ναι. Οι βοηθοί τεχνητής νοημοσύνης δημιουργούν εντολές REGEXP_REPLACE που αφαιρούν τα σημεία στίξης, ομαλοποιούν τους αριθμούς τηλεφώνου ή περικόπτουν τα κενά διαστήματα. Εκτελέστε πρώτα το μοτίβο μέσα σε ένα SELECT, επιβεβαιώστε τις ξαναγραμμένες τιμές και μόνο στη συνέχεια εφαρμόστε το σε ένα ΕΝΗΜΕΡΩΣΗ δήλωσης.

Συνοψίστε αυτήν την ανάρτηση με: