למד ביטויים רגולריים עם הקורס החינמי הזה

"יש אנשים שכאשר הם נתקלים בבעיה חושבים 'אני יודע, אשתמש בביטויים רגילים'. עכשיו יש להם שתי בעיות. " -ג'יימי זאווינסקי

עבור אנשים מסוימים, שימוש בביטויים רגולריים יכול להוות בעיה. אבל זה לא צריך להיות בעיה בשבילך. מאמר זה הוא קורס מלא בנושא ביטויים רגולריים.

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. התאם מיתרים מילוליים

בואו נמצא עכשיו את וולדו.

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/, המשמעות היא שנוכל להתאים 'תיק', 'גדול' ו'באג '.

אם אנו רוצים לחלץ את כל התנועות ממשפט, כך נוכל לעשות זאת באמצעות 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. התאמת תווים בודדים שלא צוינו

לפעמים קל יותר לציין תווים שאינך רוצה לצפות בהם. אלה נקראים 'תווים שליליים' וב- 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. מצא דמויות עם התאמה עצלנית

לפעמים התאמות הדפוס שלך יכולות להיות יותר מתוצאה אחת. לדוגמא, נניח שאני מחפש תבנית במילה titanicוהערכים המותאמים שלי חייבים להתחיל עם 't' ולסיים עם 'i'. התוצאות האפשריות שלי הן 'טיטני' ו'טי '.

זו הסיבה שלרגקס יש מושגים של 'התאמה תאבת בצע' ו'מאץ 'עצלן'.

התאמה חמדנית מוצאת את ההתאמה הארוכה ביותר האפשרית של המחרוזת המתאימה לתבנית RegEx, זהו התאמת ברירת מחדל של RegEx:

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

התאמה עצלה מוצאת את ההתאמה הקצרה ביותר האפשרית של המחרוזת המתאימה לתבנית 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' , שהוא בעצם קצרנות לביטוי רגיל רגיל. כדי להתאים את כל האותיות והמספרים שבהם אנו יכולים להשתמש \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. ציין את מספר ההתאמות העליון והתחתון

אתה יכול לציין את המספר התחתון והתחתון של התאמות תבניות עם 'מפרטי כמות'. ניתן להשתמש בהם {}בתחביר, למשל {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 שלך להסתכל בראש כדי לבדוק דפוסים בהמשך. הם שימושיים כאשר אתה מנסה לחפש מספר תבניות באותם מחרוזות. יש 2 סוגים של ראשי ראיה - חיוביים ושליליים.

Lookahead חיובי משתמש ?=בתחביר

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

מראה ראש שלילי משתמש ?!בתחביר

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. הסר את ה- Whitespace מההתחלה והסוף

הנה אתגר קטן בשבילך. כתוב RegEx שיסיר כל מרחב לבן סביב המחרוזת.

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

אם אתה נתקע או סתם רוצה לבדוק את הפתרון שלי, אל תהסס להעיף מבט בקאסט Scrimba שבו אני פותר את האתגר הזה.

34. מסקנה

מזל טוב! סיימת את הקורס הזה! אם ברצונך להמשיך ללמוד עוד, אל תהסס לבדוק את רשימת ההשמעה הזו ב- YouTube, שיש בה הרבה פרויקטים של JavaScript שתוכל ליצור.

המשיכו ללמוד ותודה על הקריאה!

כעת אתה מוכן לשחק גולף רגקס. ?