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

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

9 ασκήσεις

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

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

Μια κανονική έκφραση (ή regex) είναι μια ακολουθία χαρακτήρων που μπορούμε να χρησιμοποιήσουμε για να στοχεύσουμε και να χειριστούμε συγκεκριμένα στοιχεία μέσα σε συμβολοσειρές. Έτσι, μπορούμε να:

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

Το θέμα αυτό επικεντρώνεται στη χρήση κανονικών εκφράσεων στη JavaScript. Αν θέλεις να μάθεις πώς να γράφεις κανονικές εκφράσεις, το Eloquent JavaScript μπορεί να είναι μια καλή πηγή.

💡 Η παραλλαγή των regex της JavaScript αποτελεί μέρος του προτύπου ECMA-262 για τη γλώσσα. Αυτό σημαίνει ότι δεν χρειάζεται να ανησυχείς για συμβατότητα με συγκεκριμένους browsers.

Πώς να δημιουργείς κανονικές εκφράσεις

Στη JavaScript, οι κανονικές εκφράσεις γράφονται συνήθως με τη μορφή /pattern/modifiers, όπου το 'pattern' είναι το κύριο regex και τα 'modifiers' είναι μια σειρά χαρακτήρων που μπορούμε να προσθέσουμε για να δηλώσουμε ειδικές επιλογές (σαν υπερδυνάμεις).

Ωστόσο, υπάρχουν δύο τρόποι για να δημιουργήσεις μια κανονική έκφραση:

  1. Κυριολεκτική κανονική έκφραση:
const regex = /[a-z]/;
  1. Ο κατασκευαστής RegExp:
const regex = new RegExp('[a-z]');

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

Ο κατασκευαστής RegExp μπορεί να χρησιμοποιηθεί σε περιπτώσεις όπου το regex θα αλλάξει ή δεν το γνωρίζουμε ακόμη (όπως μια είσοδος).

🏴‍☠️ Flags

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

Μερικά από τα πιο συχνά χρησιμοποιούμενα είναι:

  • /g - Καθολική αναζήτηση
  • /i - Χωρίς διάκριση πεζών-κεφαλαίων
  • /m - Αναζήτηση σε πολλές γραμμές

Ακολουθεί ένα απλό παράδειγμα:

const re = /home/gi;
const str = 'Home, sweet home.';

str.match(re);

// => ["Home", "home"]

Ο χαρακτήρας g μάς επιτρέπει να βρίσκουμε όλες τις πιθανές αντιστοιχίες μέσα σε μια συμβολοσειρά. Χωρίς αυτή τη δυνατότητα, η JavaScript θα είχε εξάγει μόνο την πρώτη αντιστοιχία Home.

Το flag /i (χωρίς διάκριση πεζών-κεφαλαίων) μάς επιτρέπει να είμαστε ευέλικτοι όταν ψάχνουμε ένα μοτίβο. Έτσι, δεν έχει σημασία αν αυτό που ψάχνουμε είναι σε UPPERCASE ή σε lowercase.

Όταν χρησιμοποιείς τον κατασκευαστή RegExp, ο τρόπος για να προσθέσεις flags είναι διαφορετικός. Σε αυτή την περίπτωση, αρκεί να περάσεις τα flags ως δεύτερο όρισμα.

Συναρτήσεις που χρησιμοποιούνται συχνά

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

Η μέθοδος test() είναι ένας εξαιρετικός τρόπος να αναζητάς και να διαπιστώνεις αν μια τιμή-στόχος υπάρχει μέσα σε μια δεδομένη συμβολοσειρά. Έτσι, επιστρέφει μια Boolean τιμή, true ή false.

Η μέθοδος match() εξάγει την αντιστοιχία της κανονικής έκφρασης από μια δεδομένη συμβολοσειρά. Επιστρέφει έναν πίνακα με πληροφορίες και αντιστοιχίες.

Πότε να χρησιμοποιήσεις το ένα ή το άλλο; Χρησιμοποίησε το test() όταν θέλεις έναν γρήγορο τρόπο να ελέγξεις αν μια τιμή υπάρχει μέσα σε μια συμβολοσειρά, και το match() αν χρειάζεται να χρησιμοποιήσεις αυτή την τιμή ή θέλεις περισσότερες πληροφορίες για την αντιστοιχία.

Test

Η μέθοδος test() εκτελεί μια αναζήτηση για αντιστοιχία ανάμεσα σε μια κανονική έκφραση και σε μια συγκεκριμένη συμβολοσειρά. Επιστρέφει αληθή ή ψευδή τιμή.

const str = 'It is difficult to test if you have a virus';
const result = /virus$/.test(str);

console.log(result);

// => true

Match

Ωραία, αλλά τι γίνεται αν θέλουμε να πάρουμε τις πραγματικές τιμές της αναζήτησης με κανονική έκφραση;

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

Έτσι, μπορούμε και να αναζητήσουμε και να εξάγουμε πληροφορίες από οποιαδήποτε συμβολοσειρά. Για παράδειγμα:

const funnyQuote =
  'If you see someone crying, ask if it is because of their haircut.';
const regex1 = /someone/;
const regex2 = /happy/;

funnyQuote.match(regex1);
// => ["someone", index: 3, input: "If you see someone crying, ask if it is because of their haircut.", groups: undefined]

funnyQuote.match(regex2);
// => null

Όταν υπάρχει το flag /g (Καθολική αναζήτηση), αντί να πάρεις τη μοναδική αντιστοιχία μαζί με χρήσιμες πληροφορίες όπως η θέση ή η είσοδος, η μέθοδος επιστρέφει όλες τις εμφανίσεις που υπάρχουν στον πίνακα:

const funnyQuote =
  'If you see someone crying, ask if it is because of their haircut.';

const regex3 = /if/gi;

funnyQuote.match(regex3);
// => ["If", "if"];

Replace

Η μέθοδος replace() στη JavaScript μάς επιτρέπει να αναζητήσουμε μια τιμή μέσα σε μια δεδομένη συμβολοσειρά και να την αντικαταστήσουμε με μια νέα τιμή.

string.replace(searchValue, newValue);

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

let string = 'I like dogs!';
let result = string.replace('dogs', 'cats');

let string = 'I would love to travel to Japan';
let result = string.replace(/Japan/g, 'Hawaii');

Επιπλέον, μπορούμε να εφαρμόσουμε μια συνάρτηση στη θέση της αντικατάστασης, ώστε να κάνουμε επιπλέον αλλαγές σε κάθε τιμή.

let text = 'Say hello to the chatbot.';
let result = text.replace(/chatbot|hello/gi, function (word) {
  return word.toUpperCase();
});
// => "Say HELLO to the CHATBOT"

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

Split

Η μέθοδος split() στη JavaScript αποτελεί έναν διαφορετικό τρόπο χρήσης και χειρισμού συμβολοσειρών με κανονικές εκφράσεις.

Έτσι, θα χρησιμοποιήσουμε regex για να χωρίσουμε μια δεδομένη συμβολοσειρά αναγνωρίζοντας ένα μοτίβο, π.χ. str.split(/[,.\s]/). Αυτό το μοτίβο θα χρησιμοποιηθεί ως separator.

const str = 'hello,user.how are.you';

const result = str.split(/[,.\s]/);

console.log(result);
// => ['hello', 'user', 'how', 'are', 'you']

Απόδοση

Όσον αφορά την απόδοση, και οι δύο δημιουργούν ένα αντικείμενο RegExp. Η κύρια διαφορά είναι πόσο συχνά μεταγλωττίζεται το regex:

  • Με το Regular Expression Literal: μία φορά κατά την αρχική ανάλυση και μεταγλώττιση του κώδικα
  • Με τη σύνταξη RegExp(): κάθε φορά που δημιουργείται ένα νέο αντικείμενο.

Η χρήση της literal σύνταξης μπορεί να είναι καλύτερη επιλογή, όχι μόνο για λόγους απόδοσης αλλά και για απλότητα και αναγνωσιμότητα. Για περισσότερες λεπτομέρειες, δες αυτή τη συζήτηση στο Stackoverflow.

  1. Είναι πιο σύντομη και δεν σε αναγκάζει να σκέφτεσαι με όρους κατασκευαστών τύπου κλάσης.
  2. Όταν χρησιμοποιείς τον κατασκευαστή RegExp(), χρειάζεται επίσης να κάνεις escape στα εισαγωγικά και διπλό escape στις ανάποδες καθέτους. Αυτό κάνει τις κανονικές εκφράσεις, που από τη φύση τους είναι δύσκολο να διαβαστούν και να κατανοηθούν, ακόμη πιο δύσκολες.
Επεξεργασία μέσω GitHub Ο σύνδεσμος ανοίγει σε νέο παράθυρο ή καρτέλα

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