Μάθετε τακτικές εκφράσεις με αυτό το δωρεάν μάθημα

«Μερικοί άνθρωποι, όταν έρχονται αντιμέτωποι με ένα πρόβλημα, σκέφτονται« ξέρω, θα χρησιμοποιήσω κανονικές εκφράσεις ». Τώρα έχουν δύο προβλήματα. " -Jamie Zawinski

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

1. Εισαγωγή

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

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

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

Αυτό το μάθημα ακολουθεί μαζί με το πρόγραμμα σπουδών RegEx στο freeCodeCamp.org. Μπορείτε να το ελέγξετε για προκλήσεις κωδικοποίησης και να αποκτήσετε ένα πιστοποιητικό.

Αυτά τα μαθήματα επικεντρώνονται στη χρήση του RegEx σε JavaScript, αλλά οι αρχές ισχύουν σε πολλές άλλες γλώσσες προγραμματισμού που μπορεί να επιλέξετε να χρησιμοποιήσετε. Εάν δεν γνωρίζετε ήδη τη βασική JavaScript, θα ήταν χρήσιμο εάν το καλύψετε λίγο πρώτα. Έχω επίσης ένα βασικό μάθημα JavaScript στο οποίο μπορείτε να αποκτήσετε πρόσβαση στο Scrimba και στο κανάλι YouTube του freeCodeCamp.org.

Ας ξεκινήσουμε λοιπόν! Θα σώζετε την ημέρα σε χρόνο μηδέν. ;

2. Χρήση της μεθόδου δοκιμής

Για να ταιριάξουμε με τμήματα των συμβολοσειρών χρησιμοποιώντας το RegEx, πρέπει να δημιουργήσουμε μοτίβα που θα σας βοηθήσουν να κάνετε αυτήν την αντιστοίχιση. Μπορούμε να δείξουμε ότι κάτι είναι ένα μοτίβο RegEx τοποθετώντας το μοτίβο μεταξύ κάθετων /, όπως έτσι /pattern-we-want-to-match/.

Ας δούμε ένα παράδειγμα:

// We want to check the following sentencelet sentence = "The dog chased the cat."
// and this is the pattern we want to match.let regex = /the/

Παρατηρήστε πώς χρησιμοποιούμε /the/για να δείξετε ότι ψάχνουμε «το» στο δικό μας sentence.

Μπορούμε να χρησιμοποιήσουμε τη test()μέθοδο RegEx για να πούμε αν υπάρχει ένα μοτίβο σε μια συμβολοσειρά ή όχι.

// String we want to testlet myString = "Hello, World!";
// Pattern we want to findlet myRegex = /Hello/;
// result is now truelet result = myRegex.test(myString);

3. Ταιριάξτε τις γραμματικές χορδές

Ας βρούμε τώρα τον Waldo.

let waldoIsHiding = "Somewhere Waldo is hiding in this text.";let waldoRegex = /Waldo/;
// test() returns true, so result is now also truelet result = waldoRegex.test(waldoIsHiding);

Σημειώστε ότι σε αυτό το παράδειγμα waldoRegexείναι πεζά, οπότε αν γράψαμε /waldo/με πεζά γράμματα «w», τότε resultθα ήταν ψευδές.

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

Το RegEx έχει επίσης ORχειριστή που είναι |χαρακτήρας.

let petString = "James has a pet cat.";
// We can now try to find if either of the words are in the sentencelet petRegex = /dog|cat|bird|fish/;
let result = petRegex.test(petString);

5. Αγνοήστε την υπόθεση ενώ ταιριάζει

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

Για να αγνοήσουμε την περίπτωση, μπορούμε να το κάνουμε προσθέτοντας τη iσημαία στο τέλος ενός μοτίβου, όπως έτσι /some-pattern/i.

let myString = "freeCodeCamp";
// We ignore case by using 'i' flaglet fccRegex = /freecodecamp/i;
// result is truelet result = fccRegex.test(myString);

6. Εξαγωγή αγώνων

Όταν θέλουμε να εξαγάγουμε την αντίστοιχη τιμή μπορούμε να χρησιμοποιήσουμε τη match()μέθοδο.

let extractStr = "Extract the word 'coding' from this string.";
let codingRegex = /coding/;
let result = extractStr.match(codingRegex);
console.log(result);
// Terminal will show: // > ["coding"]

7. Βρείτε περισσότερα από τον πρώτο αγώνα

Τώρα όταν ξέρουμε πώς να εξαγάγουμε μία τιμή και είναι επίσης δυνατό να εξαγάγουμε πολλές τιμές χρησιμοποιώντας τη gσημαία

let testStr = "Repeat, Repeat, Repeat";
let ourRegex = /Repeat/g;
testStr.match(ourRegex); // returns ["Repeat", "Repeat", "Repeat"]

Μπορούμε επίσης να συνδυάσουμε τη gσημαία με τη iσημαία, να εξαγάγουμε πολλαπλούς αγώνες και να αγνοήσουμε το περίβλημα.

let twinkleStar = "Twinkle, twinkle, little star";
let starRegex = /twinkle/ig;// writing /twinkle/gi would have the same result.
let result = twinkleStar.match(starRegex);
console.log(result);
// Terminal will show: // > ["Twinkle", "twinkle"]

8. Ταιριάξτε οτιδήποτε με την περίοδο μπαλαντέρ

Στο RegEx .είναι ένας χαρακτήρας μπαλαντέρ που ταιριάζει με οτιδήποτε.

let humStr = "I'll hum a song";
let hugStr = "Bear hug";
// Looks for anything with 3 characters beginning with 'hu'let huRegex = /hu./;
humStr.match(huRegex); // Returns ["hum"]
hugStr.match(huRegex); // Returns ["hug"]

9. Ταιριάξτε έναν μόνο χαρακτήρα με πολλαπλές δυνατότητες

Η αντιστοίχιση οποιουδήποτε χαρακτήρα είναι ωραία, αλλά τι γίνεται αν θέλουμε να περιορίσουμε την αντιστοίχιση σε ένα προκαθορισμένο σύνολο χαρακτήρων; Μπορούμε να το κάνουμε χρησιμοποιώντας []μέσα στο RegEx μας.

Αν το έχουμε /b[aiu]g/, αυτό σημαίνει ότι μπορούμε να ταιριάξουμε με το "bag", το "big" και το "bug".

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

let quoteSample = "Beware of bugs in the above code; I have only proved it correct, not tried it.";
let vowelRegex = /[aeiou]/ig;
let result = quoteSample.match(vowelRegex);

10. Ταιριάξτε τα γράμματα του αλφαβήτου

Τι γίνεται όμως αν θέλουμε να ταιριάξουμε με μια σειρά γραμμάτων; Σίγουρα, ας το κάνουμε.

let quoteSample = "The quick brown fox jumps over the lazy dog.";
// We can match all the letters from 'a' to 'z', ignoring casing. let alphabetRegex = /[a-z]/ig;
let result = quoteSample.match(alphabetRegex);

11. Ταιριάξτε τους αριθμούς και τα γράμματα του αλφαβήτου

Τα γράμματα είναι καλά, αλλά τι γίνεται αν θέλουμε επίσης αριθμούς;

let quoteSample = "Blueberry 3.141592653s are delicious.";
// match numbers between 2 and 6 (both inclusive), // and letters between 'h' and 's'. let myRegex = /[2-6h-s]/ig;
let result = quoteSample.match(myRegex);

12. Ταίριασμα μεμονωμένων χαρακτήρων που δεν προσδιορίζονται

Μερικές φορές είναι πιο εύκολο να καθορίσετε χαρακτήρες που δεν θέλετε να παρακολουθήσετε. Αυτοί ονομάζονται "Negated Characters" και στο RegEx μπορείτε να το κάνετε χρησιμοποιώντας ^.

let quoteSample = "3 blind mice.";
// Match everything that is not a number or a vowel. let myRegex = /[^0-9aeiou]/ig;
let result = quoteSample.match(myRegex);// Returns [" ", "b", "l", "n", "d", " ", "m", "c", "."]

13. Ταίριασμα με χαρακτήρες που εμφανίζονται μία ή περισσότερες φορές

Εάν θέλετε να αντιστοιχίσετε χαρακτήρες που εμφανίζονται μία ή περισσότερες φορές, μπορείτε να χρησιμοποιήσετε +.

let difficultSpelling = "Mississippi";
let myRegex = /s+/g;
let result = difficultSpelling.match(myRegex);// Returns ["ss", "ss"]

14. Ταίριασμα χαρακτήρων που εμφανίζονται μηδέν ή περισσότερες φορές

Υπάρχει επίσης ένας *μετρητής RegEx. Αυτό ταιριάζει ακόμη και με 0 εμφανίσεις ενός χαρακτήρα. Γιατί μπορεί να είναι χρήσιμο; Τις περισσότερες φορές συνήθως σε συνδυασμό με άλλους χαρακτήρες. Ας δούμε ένα παράδειγμα.

let soccerWord = "gooooooooal!";
let gPhrase = "gut feeling";
let oPhrase = "over the moon";
// We are trying to match 'g', 'go', 'goo', 'gooo' and so on. let goRegex = /go*/;
soccerWord.match(goRegex); // Returns ["goooooooo"]
gPhrase.match(goRegex); // Returns ["g"]
oPhrase.match(goRegex); // Returns null

15. Βρείτε χαρακτήρες με Lazy Matching

Μερικές φορές οι αγώνες μοτίβου σας μπορούν να έχουν περισσότερα από ένα αποτελέσματα. Για παράδειγμα, ας πούμε ότι ψάχνω ένα μοτίβο σε μια λέξη titanicκαι οι αντίστοιχες τιμές μου πρέπει να ξεκινούν με ένα «t» και να τελειώνουν με ένα «i». Τα πιθανά αποτελέσματά μου είναι «titani» και «ti».

Γι 'αυτό το RegEx έχει τις έννοιες του «Greedy Match» και του «Lazy Match».

Η άπληστη αντιστοίχιση βρίσκει τη μεγαλύτερη δυνατή αντιστοίχιση της συμβολοσειράς που ταιριάζει στο μοτίβο RegEx, αυτή είναι μια προεπιλεγμένη αντιστοίχιση RegEx:

let string = "titanic";
let regex = /t[a-z]*i/;
string.match(regex);// Returns ["titani"]

Το Lazy match βρίσκει το συντομότερο δυνατό ταίριασμα της συμβολοσειράς που ταιριάζει στο μοτίβο RegEx και για να το χρησιμοποιήσουμε πρέπει να χρησιμοποιήσουμε ?:

let string = "titanic";
let regex = /t[a-z]*?i/;
string.match(regex);// Returns ["ti"]

16. Βρείτε έναν ή περισσότερους εγκληματίες σε ένα κυνήγι

Τώρα ας ρίξουμε μια ματιά σε μια πρόκληση RegEx. Πρέπει να βρούμε όλους τους εγκληματίες («C») σε ένα πλήθος. Γνωρίζουμε ότι μένουν πάντα μαζί και πρέπει να γράψετε ένα RegEx που θα τα βρει.

let crowd = 'P1P2P3P4P5P6CCCP7P8P9';
let reCriminals = /./; // Change this line
let matchedCriminals = crowd.match(reCriminals);

Μπορείτε να με βρείτε να περπατάω μέσα από τη λύση σε αυτό το καστ του Scrimba.

17. Ταιριάζει με μοτίβα εγχόρδων έναρξης

Το RegEx σας επιτρέπει επίσης να αντιστοιχίσετε μοτίβα που βρίσκονται μόνο στην αρχή μιας συμβολοσειράς. Έχουμε ήδη μιλήσει για τη ^δημιουργία ενός αρνητικού συνόλου. Μπορούμε να χρησιμοποιήσουμε το ίδιο σύμβολο για να βρούμε έναν αγώνα μόνο στην αρχή μιας συμβολοσειράς.

let calAndRicky = "Cal and Ricky both like racing.";
// Match 'Cal' only if it's at the beginning of a string. let calRegex = /^Cal/;
let result = calRegex.test(calAndRicky); // Returns true
let rickyAndCal = "Ricky and Cal both like racing.";
let result = calRegex.test(rickyAndCal); // Returns false

18. Μοτίβα συμβολοσειράς τελικού αγώνα

Τι γίνεται με την αντιστοίχιση ενός μοτίβου στο τέλος μιας συμβολοσειράς; Μπορούμε να το χρησιμοποιήσουμε $για αυτό.

let caboose = "The last car on a train is the caboose";
// Match 'caboose' if it's at the end of a string.let lastRegex = /caboose$/;
let result = lastRegex.test(caboose); // Returns true

19. Ταιριάξτε όλα τα γράμματα και τους αριθμούς

Νωρίτερα στα μέρη 10 και 11 σας έδειξα πώς μπορούμε να αντιστοιχίσουμε εύρη γραμμάτων και αριθμών. Εάν σας ζήτησα να γράψετε ένα RegEx που να ταιριάζει με όλα τα γράμματα και τους αριθμούς και να αγνοήσετε τις περιπτώσεις τους, μάλλον θα έχετε γράψει κάτι σαν /[a-z0-9]/giκαι αυτό είναι ακριβώς σωστό. Αλλά είναι λίγο πολύ.

Το RegEx έχει κάτι που ονομάζεται "Shorthand Character Classes" , το οποίο είναι βασικά ένα σύντομο για την κοινή έκφραση RegEx. Για \wνα _ταιριάσουμε όλα τα γράμματα και τους αριθμούς που μπορούμε να χρησιμοποιήσουμε και παίρνουμε επίσης την υπογραμμισμένη αντιστοίχιση ως μπόνους.

let quoteSample = "The five boxing wizards jump quickly.";
// Same as /[a-z0-9_]/gi to match a-z (ignore case), 0-9 and _let alphabetRegexV2 = /\w/g;
// The length of all the characters in a string// excluding spaces and the period. let result = quoteSample.match(alphabetRegexV2).length;
// Returns 31

20. Ταιριάξτε τα πάντα εκτός από γράμματα και αριθμούς

Εάν θέλουμε να κάνουμε το αντίθετο και να ταιριάξουμε με ό, τι δεν είναι γράμμα ή αριθμός (εξαιρείται επίσης η υπογράμμιση _), μπορούμε να χρησιμοποιήσουμε\W

let quoteSample = "The five boxing wizards jump quickly.";
// Match spaces and the periodlet nonAlphabetRegex = /\W/g;
let result = quoteSample.match(nonAlphabetRegex).length;
// Returns 6

21. Ταιριάξτε όλους τους αριθμούς

Εντάξει, τι γίνεται αν θέλετε μόνο αριθμούς; Υπάρχει μια σύντομη κατηγορία χαρακτήρων για αυτό; Σίγουρα, είναι \d.

let numString = "Your sandwich will be $5.00";
// Match all the numberslet numRegex = /\d/g;
let result = numString.match(numRegex).length; // Returns 3

22. Αντιστοιχίστε όλους τους μη αριθμούς

Θα θέλατε το αντίθετο και ταιριάζει με όλους τους μη αριθμούς; Χρήση\D

let numString = "Your sandwich will be $5.00";
// Match everything that is not a numberlet noNumRegex = /\D/g;
let result = numString.match(noNumRegex).length; // Returns 24

23. Περιορισμός πιθανών ονομάτων χρήστη

Μέχρι εδώ καλά! Μπράβο για να φτάσει μέχρι τώρα. Το RegEx μπορεί να είναι δύσκολο, καθώς δεν είναι ο πιο εύκολα αναγνώσιμος τρόπος κωδικοποίησης. Ας δούμε τώρα ένα πολύ πραγματικό παράδειγμα και να κάνουμε έναν επικυρωτή ονόματος χρήστη. Σε αυτήν την περίπτωση έχετε 3 απαιτήσεις:

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

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

24. Ταίριαξε στο κενό διάστημα

Μπορούμε να ταιριάξουμε με όλα τα κενά; Φυσικά, μπορούμε να χρησιμοποιήσουμε ένα στενό για αυτό και είναι\s

let sample = "Whitespace is important in separating words";
// Match all the whitespaceslet countWhiteSpace = /\s/g;
let result = sample.match(countWhiteSpace);
// Returns [" ", " ", " ", " ", " "]

25. Αντιστοιχίστε χαρακτήρες χωρίς κενό διάστημα

Μπορείτε να μαντέψετε πώς να ταιριάξετε όλους τους χαρακτήρες που δεν είναι κενά; Μπράβο, είναι \S!

let sample = "Whitespace is important in separating words";
// Match all non-whitespace characterslet countWhiteSpace = /\S/g;
let result = sample.match(countWhiteSpace);

26. Καθορίστε τον Ανώτερο και τον Κάτω αριθμό Αγώνων

Μπορείτε να καθορίσετε τον μικρότερο και τον ανώτερο αριθμό αντιστοιχιών μοτίβων με το "Quantity Specifiers". Μπορούν να χρησιμοποιηθούν με {}σύνταξη, για παράδειγμα {3,6}, πού 3είναι το κατώτερο όριο και 6είναι το ανώτερο όριο που θα ταιριάζει.

let ohStr = "Ohhh no";
// We want to match 'Oh's that have 3-6 'h' characters in it. let ohRegex = /Oh{3,6} no/;
let result = ohRegex.test(ohStr); // Returns true

27. Καθορίστε μόνο τον μικρότερο αριθμό αγώνων

Όταν θέλουμε να καθορίσουμε μόνο το κάτω όριο, μπορούμε να το κάνουμε παραλείποντας το ανώτερο όριο, για παράδειγμα για να ταιριάξουμε με τουλάχιστον τρεις χαρακτήρες που μπορούμε να γράψουμε {3,}. Παρατηρήστε ότι χρειαζόμαστε ακόμη κόμμα, ακόμα και όταν δεν καθορίζουμε το ανώτατο όριο.

let haStr = "Hazzzzah";
// Match a pattern that contains at least for 'z' characterslet haRegex = /z{4,}/;
let result = haRegex.test(haStr); // Returns true

28. Καθορίστε τον ακριβή αριθμό αγώνων

Στην προηγούμενη ενότητα ανέφερα ότι χρειαζόμαστε κόμμα {3,}όταν καθορίζουμε μόνο το κάτω όριο. Ο λόγος είναι όταν γράφετε {3}χωρίς κόμμα, αυτό σημαίνει ότι θέλετε να ταιριάξετε ακριβώς με 3 χαρακτήρες.

let timStr = "Timmmmber";
// let timRegex = /Tim{4}ber/;
let result = timRegex.test(timStr); // Returns true

29. Ελέγξτε για όλα ή Κανένα

Υπάρχουν στιγμές που μπορεί να θέλετε να καθορίσετε μια πιθανή ύπαρξη ενός χαρακτήρα στο μοτίβο σας. Όταν ένα γράμμα ή ένας αριθμός είναι προαιρετικός και θα το χρησιμοποιούσαμε ?.

// We want to match both British and American English spellings // of the word 'favourite'
let favWord_US = "favorite";let favWord_GB = "favourite";
// We match both 'favorite' and 'favourite' // by specifying that 'u' character is optionallet favRegex = /favou?rite/; // Change this line
let result1 = favRegex.test(favWord_US); // Returns truelet result2 = favRegex.test(favWord_GB); // Returns true

30. Θετική και αρνητική ματιά

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

Το θετικό lookahead χρησιμοποιεί ?=σύνταξη

let quit = "qu";
// We match 'q' only if it has 'u' after it. let quRegex= /q(?=u)/;
quit.match(quRegex); // Returns ["q"]

Το αρνητικό lookahead χρησιμοποιεί ?!σύνταξη

let noquit = "qt";
// We match 'q' only if there is no 'u' after it. let qRegex = /q(?!u)/;
noquit.match(qRegex); // Returns ["q"]

31. Επαναχρησιμοποίηση μοτίβων χρησιμοποιώντας ομάδες καταγραφής

Ας φανταστούμε ότι πρέπει να καταγράψουμε ένα επαναλαμβανόμενο μοτίβο.

let repeatStr = "regex regex";
// We want to match letters followed by space and then letterslet repeatRegex = /(\w+)\s(\w+)/;
repeatRegex.test(repeatStr); // Returns true

Αντί να επαναλαμβάνουμε (\w+)στο τέλος, μπορούμε να πούμε στο RegEx να επαναλάβει το μοτίβο, χρησιμοποιώντας \1. Έτσι, το ίδιο όπως παραπάνω μπορεί να γραφτεί ξανά ως:

let repeatStr = "regex regex";
let repeatRegex = /(\w+)\s\1)/;
repeatRegex.test(repeatStr); // Returns true

32. Χρησιμοποιήστε ομάδες καταγραφής για αναζήτηση και αντικατάσταση

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

let wrongText = "The sky is silver.";
let silverRegex = /silver/;
wrongText.replace(silverRegex, "blue");
// Returns "The sky is blue."

33. Καταργήστε το κενό διάστημα από την αρχή και το τέλος

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

let hello = " Hello, World! ";
let wsRegex = /change/; // Change this line
let result = hello; // Change this line

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

34. Συμπέρασμα

Συγχαρητήρια! Έχετε τελειώσει αυτό το μάθημα! Εάν θέλετε να συνεχίσετε να μαθαίνετε περισσότερα, μη διστάσετε να ρίξετε μια ματιά σε αυτήν τη λίστα αναπαραγωγής YouTube, η οποία διαθέτει πολλά έργα JavaScript που μπορείτε να δημιουργήσετε.

Συνεχίστε να μαθαίνετε και ευχαριστώ για την ανάγνωση!

Τώρα είστε έτοιμοι να παίξετε γκολφ regex. ;