Lær Regular Expressions med dette gratis kursus

”Nogle mennesker, når de står over for et problem, tænker 'jeg ved, jeg bruger regelmæssige udtryk.' Nu har de to problemer. ” -Jamie Zawinski

For nogle mennesker kan brug af regulære udtryk være et problem. Men det behøver ikke at være et problem for dig. Denne artikel er et fuldt kursus om Regular Expressions.

1. Introduktion

Regular Expressions, eller bare RegEx, bruges i næsten alle programmeringssprog til at definere et søgemønster, der kan bruges til at søge efter ting i en streng.

Jeg har udviklet et gratis, komplet videokursus på Scrimba.com for at lære det grundlæggende i regulære udtryk.

Denne artikel indeholder kurset i skriftlig form. Men hvis du foretrækker at se videoversionen med interaktive lektioner, kan du tjekke den på Scrimba. Afsnittene i denne artikel svarer til sektionerne i Scimba-kurset.

Dette kursus følger sammen med RegEx-læseplanen på freeCodeCamp.org. Du kan tjekke det for kodningsudfordringer og for at optjene et certifikat.

Disse lektioner fokuserer på at bruge RegEx i JavaScript, men principperne gælder i mange andre programmeringssprog, du måske vælger at bruge. Hvis du ikke allerede kender grundlæggende JavaScript, kan det være nyttigt, hvis du først dækker det lidt. Jeg har også et grundlæggende JavaScript-kursus, som du kan få adgang til på Scrimba og på YouTube-kanalen freeCodeCamp.org.

Så lad os komme i gang! Du sparer dagen på ingen tid. ?

2. Brug af testmetoden

For at matche dele af strenge ved hjælp af RegEx er vi nødt til at oprette mønstre, der hjælper dig med at udføre den matchning. Vi kan indikere, at noget er et RegEx-mønster ved at placere mønsteret mellem skråstreger /, sådan /pattern-we-want-to-match/.

Lad os se på et eksempel:

// 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/

Læg mærke til, hvordan vi bruger /the/til at indikere, at vi leder efter "the" i vores sentence.

Vi kan bruge RegEx- test()metoden til at fortælle, om et mønster er til stede i en streng eller ikke.

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

3. Match bogstavelige strenge

Lad os nu finde 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);

Bemærk, at i dette eksempel waldoRegexer /waldo/store og små bogstaver , så hvis vi skulle skrive med små bogstaver 'w', ville vores resultvære falsk.

4. Match en bogstavelig streng med forskellige muligheder

RegEx har også ORoperatør, som er |karakter.

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. Ignorer sagen, mens den matcher

Indtil videre har vi set på mønstre, når tilfældene med brevene havde betydning. Hvordan kan vi gøre vores RegEx-mønstre til at være store og små bogstaver?

For at ignorere tilfælde kan vi gøre det ved at tilføje iflag i slutningen af ​​et mønster, sådan /some-pattern/i.

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

6. Uddrag matches

Når vi vil udtrække den matchede værdi, kan vi bruge match()metoden.

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. Find mere end den første kamp

Nu når vi ved, hvordan man udtrækker en værdi, og det er også muligt at udtrække flere værdier ved hjælp af gflag

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

Vi kan også kombinere gflag med iflag for at udtrække flere kampe og ignorere kabinet.

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. Match alt med jokertegnperioden

I RegEx .er der et jokertegn, der passer til noget.

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. Match en enkelt figur med flere muligheder

At matche ethvert tegn er rart, men hvad hvis vi vil begrænse matchningen til et foruddefineret sæt tegn? Det kan vi gøre ved at bruge []inde i vores RegEx.

Hvis vi har /b[aiu]g/det, betyder det, at vi kan matche 'taske', 'stor' og 'bug'.

Hvis vi vil udtrække alle vokaler fra en sætning, kan vi gøre det ved hjælp af 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. Match bogstaverne i alfabetet

Men hvad hvis vi vil matche en række bogstaver? Sikker på, lad os gøre det.

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. Match numre og bogstaver i alfabetet

Bogstaver er gode, men hvad hvis vi også vil have tal?

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. Match enkelttegn ikke specificeret

Nogle gange er det lettere at specificere tegn, som du ikke vil se. Disse kaldes 'Negated Characters' og i RegEx kan du gøre det ved hjælp af ^.

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. Match tegn, der forekommer en eller flere gange

Hvis du vil matche et tegn, der forekommer en eller flere gange, kan du bruge +.

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

14. Match tegn, der forekommer nul eller flere gange

Der er også en *RegEx-kvantifier. Denne matcher endda 0 forekomster af et tegn. Hvorfor kan dette være nyttigt? Det meste af tiden er det normalt i kombination med andre tegn. Lad os se på et eksempel.

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. Find figurer med Lazy Matching

Nogle gange kan dine mønsterkampe have mere end et resultat. Lad os for eksempel sige, at jeg leder efter et mønster i et ord, titanicog mine matchede værdier skal begynde med et 't' og slutte med et 'jeg'. Mine mulige resultater er 'titani' og 'ti'.

Dette er grunden til, at RegEx har begreberne 'Greedy Match' og 'Lazy Match'.

Grådigt match finder den længst mulige match af strengen, der passer til RegEx-mønsteret, dette er et standard RegEx-match:

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

Lazy match finder den kortest mulige match af strengen, der passer til RegEx-mønsteret, og for at bruge det skal vi bruge ?:

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

16. Find en eller flere kriminelle i en jagt

Lad os nu se på en RegEx-udfordring. Vi er nødt til at finde alle de kriminelle ('C') i en skare. Vi ved, at de altid forbliver sammen, og at du skal skrive en RegEx, der kan finde dem.

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

Du kan finde mig gå gennem løsningen i denne Scrimba-rollebesætning.

17. Match begyndende strengmønstre

RegEx giver dig også mulighed for at matche mønstre, der kun er i begyndelsen af ​​en streng. Vi har allerede talt om at ^skabe et negerende sæt. Vi kan bruge det samme symbol for at finde et match kun ved begyndelsen af en streng.

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. Match slutende strengmønstre

Hvad med at matche et mønster i slutningen af ​​en streng? Det kan vi bruge $til.

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. Match alle bogstaver og tal

Tidligere i del 10 og 11 viste jeg dig, hvordan vi kan matche intervaller med bogstaver og tal. Hvis jeg bad dig om at skrive en RegEx, der matcher alle bogstaver og tal og ignorere deres sager, ville du sandsynligvis have skrevet noget lignende, /[a-z0-9]/giog det er helt rigtigt. Men det er lidt for længe.

RegEx har noget kaldet 'Shorthand Character Classes' , som grundlæggende er en stenografi for almindeligt RegEx-udtryk. For at matche alle bogstaver og tal, vi kan bruge, \wog vi får også _matchet understregning som en bonus.

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. Match alt undtagen bogstaver og tal

Hvis vi vil gøre det modsatte og matche alt, hvad der ikke er et bogstav eller et tal (udelukker også understregning _), kan vi bruge\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. Match alle numre

Okay, hvad med hvis du kun vil have tal? Er der en stenografisk karakterklasse til det? Sikker på, det er det \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. Match alle ikke-numre

Vil du have det modsatte og matche alle ikke-numre? Brug\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. Begræns mulige brugernavne

Så langt så godt! Godt gået for at komme så langt. RegEx kan være vanskelig, da det ikke er den mest læsbare måde at kode på. Lad os nu se på et meget virkeligt eksempel og lave et brugernavn validator. I dette tilfælde har du 3 krav:

  • Hvis der er tal, skal de være i slutningen.
  • Bogstaver kan være små og store bogstaver.
  • Mindst to tegn lange. Navne på to bogstaver kan ikke have tal.

Prøv at løse dette alene, og hvis du finder det svært eller bare vil tjekke svaret, skal du tjekke min løsning.

24. Match hvidt mellemrum

Kan vi matche alle de hvide rum? Selvfølgelig kan vi også bruge en stenografi til det, og det er det\s

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

25. Match ikke-mellemrumstegn

Kan du gætte, hvordan du matcher alle tegn, der ikke er mellemrum? Godt gået, det er det \S!

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

26. Angiv øvre og nedre antal matches

Du kan angive det nedre og det øvre antal mønstertilpasninger med 'Mængdespecifikatorer'. De kan f.eks. Bruges med {}syntaks, {3,6}hvor 3er den nedre grænse og 6den øvre grænse, der skal matches.

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. Angiv kun det laveste antal matches

Når vi kun ønsker at specificere den nedre grænse, kan vi gøre det ved at udelade den øvre grænse, for eksempel for at matche mindst tre tegn, vi kan skrive {3,}. Bemærk, at vi stadig har brug for et komma, selv når vi ikke angiver den øvre grænse.

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

28. Angiv nøjagtigt antal matches

I det forrige afsnit nævnte jeg, at vi har brug for et komma, {3,}når vi kun angiver den nedre grænse. Årsagen er, når du skriver {3}uden komma, betyder det, at du ønsker at matche nøjagtigt 3 tegn.

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

29. Kontroller for alle eller ingen

Der er tidspunkter, hvor du måske vil specificere en mulig eksistens af et tegn i dit mønster. Når et bogstav eller et tal er valgfrit, og vi bruger det ?til.

// 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. Positiv og negativ lookahead

' Lookaheads ' er mønstre, der fortæller din JS at lookahead skal kontrollere mønstre længere. De er nyttige, når du prøver at søge efter flere mønstre i de samme strenge. Der er 2 typer lookahoveder - positive og negative.

Positiv lookahead bruger ?=syntaks

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

Negativ lookahead bruger ?!syntaks

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

31. Genbrug mønstre ved hjælp af fangstgrupper

Lad os forestille os, at vi er nødt til at fange et gentaget mønster.

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

I stedet for at gentage (\w+)i slutningen kan vi bede RegEx om at gentage mønsteret ved hjælp af \1. Så det samme som ovenfor kan skrives igen som:

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

32. Brug Capture Groups til at søge og erstatte

Når vi finder et match, er det undertiden praktisk at erstatte det med noget andet. Vi kan bruge replace()metoden til det.

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

33. Fjern Whitespace fra Start og End

Her er en lille udfordring for dig. Skriv en RegEx, der fjerner ethvert mellemrum omkring strengen.

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

Hvis du sidder fast eller bare vil tjekke min løsning, er du velkommen til at kigge på Scrimba-rollebesætningen, hvor jeg løser denne udfordring.

34. Konklusion

Tillykke! Du er færdig med dette kursus! Hvis du gerne vil fortsætte med at lære mere, er du velkommen til at tjekke denne YouTube-playliste, der har mange JavaScript-projekter, du kan oprette.

Bliv ved med at lære og tak for læsningen!

Du er nu klar til at spille regex golf. ?