[Powered by Google Translate] [סמינר: התאמת דפוסים עם ביטויים רגולריים] [אוניברסיטת ג'ון מוסמן-הרווארד] [זה CS50.-CS50.TV] אוקיי. ובכן, ברוכים הבאים לכולם. זה CS50 2012. שמי ג'ון, ואני יהיה לדבר היום על ביטויים רגולריים. ביטויים רגולריים הוא בעיקר כלי, אלא גם משמשים לעתים בקוד באופן פעיל כדי להתאים דפוסים ומחרוזות במהות. אז הנה קומיקס אינטרנט מxkcd. בקומיקס הזה יש תעלומת רצח שבו יש לו את הרוצח אחרי שמישהו בחופשה, ויש לי את הגיבורים ל לחפש דרך 200 מגה בייט של הודעות דוא"ל המחפשים כתובת. והם עומדים לוותר כאשר מישהו שמכיר ביטויים רגולריים - ככל הנראה גיבור - נוחת למטה וכותב קצת קוד ופותר את תעלומת הרצח. אז כנראה שיהיה משהו שאתה יהיה מוסמך לעשות לאחר הסמינר הזה. אנחנו רק הולכים לספק מבוא תמציתי לשפה ולתת לך מספיק אמצעים כדי ללכת אחרי יותר משאבים בעצמך. ביטויים כל כך רגילים לחפש בעצם כמו זה. זה ביטוי רגיל ברובי. זה לא שונה מאוד בין שפות. יש לנו רק על לוכסנים להתחיל ולסמן את הביטוי הרגיל ברובי. ואת זה הוא ביטוי רגיל לחפש בתבנית כתובת דואר אלקטרוני. כך אנו רואים בתחילה קצת נראה לכל תו אלפאנומרי. זאת משום שכתובות דואר אלקטרוני לעתים קרובות יש להתחיל עם אופי אלפביתי. ואז כל תו מיוחד ואחריו הסימן @. ולאחר מכן את אותו דבר עבור שם הדומיין. ולאחר מכן תווים בין 2 ל 4 לחפש. Com,. נטו, וכן הלאה. אז זה הוא דוגמה נוספת לביטוי רגיל. ביטויים כל כך רגילים הם פרוטוקולים למציאת הדפוסים בטקסט. הם עושים השוואות, בחירות, והחלפות. אז דוגמה שלישית היא למצוא את כל מספרי הטלפון שהסתיימו ב54 בספרייה. אז לפני שקורע את דוד ספריית CS50 אנחנו יכולים לחפש דפוס שבו יש לנו סוגריים אז 3 מספרים אז בסופו הסוגריים, 3 מספרים נוספים, מקף, 2 מספרים, ולאחר מכן 54. וזה יהיה בעצם איך אנחנו באים עם ביטוי רגיל כדי לחפש את זה. אז יש - שעשינו כמה דברים בCS50 שהם קצת כמו ביטויים רגילים, ולכן - לדוגמה - בקובץ dictionary.C לקבוצת הבעיה בדיקת האיות ייתכן שהשתמשת fscanf לקרוא במילה מהמילון. ואתה יכול לראות את 45s אחוז הוא מחפש מחרוזת של 45 תווים. אז זה קצת כמו ביטוי בסיסי קבוע. ואתה יכול לקבל את כל תווים 45 שמתאימים את החשבון לשם ולהרים אותם למעלה. ולאחר מכן הדוגמא השנייה בבעיה תכנות האינטרנט האחרונה להגדיר בקוד ההפצה עבור PHP שאנחנו עושים בעצם צריכים פשוט ביטוי קבוע. ואת זה הוא פשוט מחפש כדי לבדוק אם דף האינטרנט שהוא עבר ב מתאים גם התחברות והתנתקות הרשמה. PHP. ולאחר מכן חוזר אמת או שקר שמבוסס על התאמת הביטוי רגילה. לכן, כאשר אתם משתמשים בביטוי רגיל? למה אתה כאן היום? אז אתה לא רוצה להשתמש בביטוי רגיל, כאשר יש משהו ש עושה את העבודה בשבילך אפילו יותר בקלות. אז XML ו-HTML הם למעשה די מסובך לכתוב ביטויים רגולריים לכפי שנראה בקצת. אז יש מנתחים ייעודיים לשפות אלו. אתה גם צריך להיות בסדר עם offs הסחר והדיוק בתדירות גבוהה. אם אתה מנסה - כך ראינו ביטוי רגיל לכתובת דוא"ל, אבל אמרת שאתה רוצה את כתובת הדוא"ל של ספציפית ובהדרגה ביטוי רגיל עלול להפוך למורכב יותר ככל שזה הפך מדויק יותר. אז זה יהיה אחד מסחר. אתה צריך להיות בטוח שאתה בסדר עושה עם הביטוי הרגיל. אם אתה יודע בדיוק מה אתה מחפש זה אולי הגיוני יותר כדי להשקיע את הזמן ולכתוב מנתח יעיל יותר. וסוף סוף יש בעיה היסטורי עם הסדירות ביטויים ושפות. ביטויים רגולריים הם למעשה הרבה יותר חזק מאשר ביטויים רגולריים לאומרים במובן פורמלי. אז אני לא רוצה ללכת רחוק מדי לתאוריה הרשמית, אך רוב השפות שלמעשה קוד שבאנחנו לא רגילים. ובגלל זה בביטויים רגילים לפעמים לא נחשבים כל כך בטוח. אז בעצם יש היררכית חומסקי לשפות, וביטויים רגולריים הם לבנות באמצעות איחוד, שרשור, ופעולת כוכב Kleene כי אנו רואים בכמה דקות. אם אתם מעוניינים בתאוריה יש די הרבה קורה שם מתחת למכסת המנוע. אז היסטוריה קצרה - רק בשביל ההקשר כאן - סטים רגילים באו בשנת 1950, ולאחר מכן היו לנו עורכים פשוט כי התאגד בביטויים רגילים - פשוט מחפש מחרוזות. Grep - אשר הוא כלי שורת פקודת - היה אחד הראשונים כלים מאוד פופולריים ששולבו בביטויים רגילים ב -1960. בשנתי ה -80, פרל נבנה - היא שפת תכנות ש משלב ביטויים רגולריים באופן בולט מאוד. ואז לאחרונה היה לנו פרל ביטוי תואם רגיל פרוטוקולים בעצם בשפות אחרות המשתמשות בהרבה מאותו התחביר. כמובן שהאירוע החשוב ביותר היה בשנת 2008 שבו היה יום הרגיל הלאומי הראשון ביטויים, שאני מאמין הוא 1 יוני אם אתה רוצה לחגוג את זה. שוב, רק קצת יותר תיאוריית כאן. אז יש כמה דרכים לבניית ביטויים רגולריים שונות. דרך פשוטה אחת היא לבנות את הביטוי שאתה הולך לרוץ על המחרוזת לפרש - בעצם לבנות מיני תכנית קטנה ש ינתח חתיכות של חוט ולראות, "הו, האם זה יתאים ביטוי הרגיל או לא?" ולאחר מכן להפעיל את זה. אז אם יש לך ביטוי קטן מאוד רגיל, זה כנראה הדרך היעילה ביותר לעשות את זה. ואז אם אתה - אפשרות נוספת היא לשמור על בנייה מחדש ביטוי כמו שאתה הולך, וכי הוא האפשרות לדמות. והניסיונות המוקדמים אלה באלגוריתמי ביטוי רגילים היו יחסית פשוט ומהיר יחסית, אבל לא היה לי הרבה גמישות. אז כדי לעשות אפילו חלק מהדברים שאנחנו הולכים להסתכל על היום יש לנו היה צריך לעשות ביטוי מורכב יותר קבוע יישומים שעשויים להיות איטיות הרבה יותר, כך שהוא משהו לזכור יש גם הכחשת ביטויים קבועה של מגוון התקפה כי לנצל את הפוטנציאל עבור יישומים חדשים אלה של ביטויים רגילים להיות מאוד מורכב. והרבה באותה התחושה שראינו בהתקפות הצפת מאגר, יש לך התקפות כי עבודה על ידי ביצוע לולאות רקורסיבית ש הצפת הקיבולת של זיכרון. ודרך אגב Regexen היא אחת מהצורות הרבות הרשמיות של ביטוי רגיל על ידי אנלוגיה לשוורים באנגלו סכסון. אוקיי, אז ספריית פייתון רבים מכם כאן באדם שיש לי מחשבי מקינטוש, כך למעשה אתה יכול למשוך את זה על המסך שלך. ביטויים רגולריים בנויים לתוך פייתון. וכך פייתון הוא מראש על מחשבי מק וגם באינטרנט בקישור הזה. אז אם אתם צופים בך יכול לעצור ולוודא שיש לך פייתון כמו שאנחנו משחקים כאן בסביבה. יש באינטרנט מדריך ל, כך שאם אתה פשוט להקליד לתוך המחשב פייתון אתה תראה שהגרסה עולה במסוף. אז סיפק קישור למדריך לגרסת 2 של פייתון, כמו גם גיליון לרמות. יש גרסה 3 של פייתון, אבל Mac שלך לא בהכרח באנו עם זה מראש. אז לא נורא שונה. אוקיי, אז כמה עקרונות בסיסיים של שימוש בביטויים רגילים בפייתון. אז הנה אני משמש ביטוי מאוד פשוט, אז עשיתי מחדש יבוא פייתון ולאחר מכן לקח את התוצאה של re.search. והחיפוש לוקח 2 טענות. הראשון הוא הביטוי הרגיל, והשני הוא הטקסט או מחרוזת שברצונך לנתח. ואז הדפסתי result.group. אז אלה הם 2 פונקציות בסיסיות אנחנו הולכים לראות היום ללמוד על ביטויים רגולריים. אז רק פירוק ביטוי רגיל זה כאן שעות ולאחר מכן \ W ולאחר מכן מ 'כך \ W פשוט מקבל כל תו בא"ב לשם. אז הנה אנחנו מחפשים "שעות" ולאחר מכן דמות אחרת אלפביתי ולאחר מכן מ ', כך שיתאים לכאן בשר חזיר ב", כריכי אברהם לינקולן ובשר חזיר ". זו היא התוצאה של אותה הקבוצה. דבר נוסף שאנו יכולים לעשות הוא להשתמש במחרוזות לפנינו של טקסט בפייתון. אז אני מניח שאני אלך קדימה ולמשוך את זה כאן. מחדש יבוא פייתון. ואם הייתי עושה את אותו הדבר - תן לנו לומר הוא טקסט, "אברהם," תן לנו להתקרב - שם אנחנו הולכים. טקסט הוא: "אברהם אוכל בשר חזיר." אוקיי, ולאחר מכן לגרום = re.search. ואז הביטוי שלנו יכול להיות שעות, ולאחר מכן אני אעשה נקודה מ '. אז הנקודה פשוט לוקחת כל תו שהוא לא קו חדש כולל מספרים, סימני אחוז, משהו כזה. ולאחר מכן טקסט - בום - ולאחר מכן result.group--כן. אז זה בדיוק כיצד ליישם את הפונקציונליות בסיסית כאן. אם היו לנו טבעת טקסט - טקסט מטורף ש-- כלל אומרים המון חתכים בגב ובתוך מחרוזות ודברים שיכולים להיראות כמו רצפים להימלט, אז אנחנו כנראה רוצים להשתמש בקלט הטקסט הגולמי כדי לוודא שהוא קיבל. וזה רק נראה ככה. אז אם אנחנו מחפשים בכל אחד מהם יש אנחנו לא צריכים למצוא שום דבר. אבל זה איך היית ליישם אותה, רק לפני המחרוזת של הביטוי הרגיל אתה שם את אות ר '. אוקיי, אז תן לנו להמשיך. בסדר - אז הבה נתבונן בכמה דפוסים חוזרים כאן. אז דבר אחד שאתה רוצה לעשות הוא לחזור על דברים כמו שאתה מחפש דרך טקסט. אז כדי לעשות אחריו מספר כלשהו של b - אתה עושה AB *. ואז יש סדרה של חוקים אחרים. ואתה יכול להסתכל למעלה כל אלה, אני פשוט ארוץ דרך כמה אלה נפוצים ביותר. אז AB + הוא ואחריו כל N גדול מ -0 של b. ab? הוא ואחריו 0 או 1 של b. ab {N} הוא ואחריו N של B, ולאחר מכן כן הלאה. אם יש לך 2 מספרים בסוגריים המסולסלים אתה ציון טווח יכול להיות שאולי מתאים. אז אנחנו ייראו יותר בכמה דפוסים חוזרים ונשנים בדקה. אז 2 דברים שכדאי לזכור בעת שימוש בתבנית התאמת כלים אלה כאן. אז אומרים שאנחנו רוצים להסתכל על HM של "אברהם לינקולן עושה כריכי בשר חזיר". אז שיניתי את שמו של אברהם לינקולן לאברהם. ועכשיו אנחנו מחפשים את מה שהוחזר על ידי פונקצית חיפוש זה, וזה רק מחזיר את בשר חזיר במקרה זה. והיא עושה את זה כי החיפוש פשוט לוקח את התור השמאלי ביותר באופן טבעי. וכל הביטויים הרגילים, אלא אם כן תציינו אחר יעשו את זה. אם אנחנו רוצים למצוא את כל מה שיש פונקציה לזה - למצוא הכל. כך שרק יכלו להיראות כמו כל = re.findall ('h.m', טקסט) ולאחר מכן all.group (). הכל מייצר גם בשר חזיר ובשר חזיר, ובמקרה זה גם של המיתרים באברהם כל בשר חזיר. אז זה עוד אפשרות. גדול. הדבר השני שיש לזכור הוא שביטויים רגולריים לקחת הגדול ביותר באופן אינטואיטיבי. תנו לנו להסתכל על דוגמה זו. אנחנו עשינו את זה ביותר החיפוש ממני כאן, ולאחר מכן ניסיתי חיפוש גדול יותר באמצעות מפעיל כוכב Kleene. אז ל, "אברהם לינקולן עושה כריכי בשר חזיר," ויש לי רק חזרה מ 'כתוצאה מכך. הסיבה לטעות שהייתה שאני היה יכול לקחת את כל מספר של שעות בגלל שלא ציינו דבר ללכת בשעות בין מ. הדוגמא היחידה שם שהייתה מ '- דוגמאות רק שם עם מ' בזה וכל מספר שעות של היה פשוט מ 'החוט. אחר כך ניסיתי את זה שוב, אני אמרתי, "בסדר, תן לנו לקבל את הקבוצה בפועל הגדולה ביותר כאן". ואז עשיתי שעות. * מ ', כך שרק מחזיר את כל מספרים ותווים בין שעות ודקות. ואם אתה רק מתחיל וחושב, "אה, בסדר, גם זה יהיה תבין אותי בשר חזיר, "זה לוקח כל דבר, החל בשעות למעשה אברהם לינקולן כל הדרך עד לסופו של חזיר. זה חמדן, זה רואה ש - כל הטקסט הזה אחר - מ ', וזה מה שזה לוקח פנימה זה בוטה במיוחד - זו היא תכונה שאנחנו יכולים גם לציין לזה לא להיות חמדנים שימוש בפונקציות אחרות. אבל זה משהו שאנחנו צריכים לזכור במיוחד כאשר מסתכלים בטקסט HTML, וזו אחת סיבות ש ביטויים רגולריים הם קשים עבור ה-HTML. כי אם יש לך תג HTML פתוח ולאחר מכן המון דברים באמצע ועוד קצת HTML אחר נסגר תג הרבה יותר מאוחר בתכנית, יש לך רק נאכל הרבה קוד ה-HTML שלך אולי בטעות. בסדר - דמויות כל כך יותר מיוחדות, כמו שפות רבות אחרות, אנו לברוח באמצעות הקו הנטוי. אז אנחנו יכולים להשתמש בנקודה כדי לציין כל תו למעט שורה חדשה. אנחנו יכולים להשתמש בבריחת w כדי לציין כל תו אלפביתי. ועל ידי ד בריחת אנלוגיה לכל מספר שלם - אופי מספרי. אנו יכולים לציין - אנחנו יכולים להשתמש בסוגריים כדי לציין ביטויים קשורים. אז זה היה מקבל A, B, או C. ואנחנו גם יכולים לציין או אפשרויות לאחד או ב. לדוגמה - אם אנחנו מחפשים אפשרויות מרובות בסוגריים שאנחנו יכולים להשתמש המפעיל או כב-- אז בוא נחזור לדוגמה זו כאן. ועכשיו הרשה לנו לקחת - תן לנו לחזור לדוגמה זו כאן, ולאחר מכן לקחת AE - כך זה צריך לחזור - אני מניח שזה עדיין אברהם. אז זה - אם אנחנו עושים את כל - גדולים. אז הרשה לנו לעדכן את הטקסט כאן. "אברהם אוכל חזיר תוך המהומים -. תוך המינג" גדול. הכל. גדול. עכשיו אנחנו מקבלים בשר חזיר, בשר חזיר, ומכפלת. בעוד המינג - בעוד מזמזם לו - ואילו זמזם לאמרתו. גדול. אותו דבר. עכשיו כל מה שמחזיר עדיין רק בשר חזיר, בשר חזיר, ומכפלת בלי להרים על הזמזום או לו. גדול - אז מה אם אנחנו רוצים להסתכל או ש-- כדי שנוכל גם לעשות לו או - אנחנו נחזור לזה. אוקיי - כך - בסדר - בתפקידים שאתה יכול גם להשתמש בתו או סימן הדולר כדי לציין שאתם מחפשים משהו בתחילת או בסוף המחרוזת. או התחלה או הסוף של מילה. זוהי דרך אחת להשתמש בזה. אוקיי - אז תן לנו לשחק עם בלוק של טקסט מעט גדול יותר. תן לנו לומר את השורה הזו כאן - הצהרה זו כאן. כוחו של ביטוי הרגיל הוא שהם יכולים לציין דפוסים לא רק קבוע תווים. תן לנו לעשות - תנו לנו להתקשר אל בלוק זה. אז תוכל לקרוא את כל זה פנימה ואז יש לי - תן לנו לעשות את כל =; אז מה הם כמה דברים שאנחנו יכולים לחפש ברווחיים כאן? אנחנו יכולים להסתכל לאוזן הביטוי. לא מאוד מעניין. מה דעתך על זה? נצטרך לראות מה קורה. נתתי לו בעיה. אז כל מספר של דברים לפני מחדש וכל. כך שצריך להחזיר את הכל מההתחלה עד כל מחדש אולי כמה פעמים. ואז כאן יש לנו את כוח של ביטויים רגולריים הוא שהם ניתן לציין דפוסים לא רק דמויות כאן. אז כל הדרך עד לגמר מחדש, זה התחיל עם הכי שמאלי והיה חמדן. תן לנו לראות - מה עוד אנחנו יכולים לחפש. אני מניח שדבר אחד אם היית מעוניינים במחפש את כינויים שהיא והוא, אתה יכול לבדוק אם זה שווה ל -0 או 1 וביטויו, ושהוא כנראה לא הולך לחזור - אה, אני מניח שזה בגלל שיש לו חזר אנחנו מסתכלים על כוח, באותו יום, כאן. הבה תנסו לציין שזה צריך לבוא בהתחלה של משהו. תן לנו לראות אם זה יורד לכיוון שער. אז אנחנו יכולים לעשות את שומן, ויש לנו לא מקבלים שום דבר, כי היא והוא לא מתרחש בביטוי הזה. גדול. אוקיי - אז בחזרה לחתול כאן. דפוסים מורכבים כל כך פוגע במוח. אז זו הסיבה שאנו משתמשים בביטויים רגילים, כדי למנוע בעיות אלה. אז הנה כמה מצבים שימושיים אחרים שאתה יכול לשחק עם סביב. אנחנו הבטנו בחיפוש היום, אבל אתה יכול גם להשתמש בהתאמה, פיצול, findall, וקבוצות. דברים מגניבים אחרים אז אתה יכול לעשות עם ביטויים רגולריים חוץ מזה רק מחפש דפוסים הוא לוקח תבנית ומחזיק את כל המשחקים - המשתנים שלה - ולאחר מכן באמצעות אלה בקוד שלך בשלב מאוחר יותר. זה יכול להיות מועיל למדי. דברים אחרים עשויים להיות לספור. אז אנחנו יכולים לספור את מספר המופעים של תבנית ביטוי רגילה, וזה מה שאנחנו יכולים להשתמש בקבוצות ל. והמצבים אחרים, כמו גם גם אפשרי. אז אני רק רוצה לדבר קצת יותר על דרכים אחרות אתה יכול להשתמש בביטויים רגילים. אז יישום מתקדם יותר אחד הוא בהתאמה מטושטשת. אז אם אתם מחפשים טקסט לביטוי, יוליוס קיסר, ואתה רואה גם גאיוס יוליוס קיסר או את השם יוליוס קיסר בשפות אחרות, אז אולי אתה גם רוצה להקצות קצת משקל לערכים אלו. ואם הוא קרוב מספיק - אם הוא חוצה סף מסוים - אז אתה רוצה כדי להיות מסוגל לקבל את יוליוס הקיסר. אז יש כמה מימושים שונים שלבעוד כמה שפות אחרות גם כן. הנה כמה כלים אחרים, Regex PAL - אפליקציה קטנה ונחמדה באינטרנט כדי לבדוק אם הביטויים הרגילים שלך מורכבים בצורה נכונה. ישנם גם כלים עצמאיים שניתן להפעיל משולחן העבודה שלך כמו פיקו Ultra, וכמו גם ספרי בישול בלבד. אז אם אתה עושה פרויקט שיש בו טונות של ביטויים רגולריים זה כנראה המקום ללכת אל מחוץ להיקף של היום. ולאחר מכן, רק כדי לתת לך תחושה של כמה נפוץ הוא יש grep ביוניקס, יש פרל מובנית, ו-C יש PCRE לג ויש לי אז כל אלה שפות אחרות גם חבילות ביטוי רגולרי שפועלים עם רמה דומה של תחביר שיש לנו טעם של היום. PHP, Java, רובי, וכן הלאה. חיפוש קוד גוגל הוא למעשה שווה אזכור, הוא אחד מספר קטן יחסית של יישומים שם בחוץ, כי מאפשר לציבור הגישה מסד הנתונים שלה תוך שימוש בביטויים רגילים. אז אם אתה מסתכל על קוד חיפוש של Google אתה יכול למצוא את הקוד אם אתם מחפשים דוגמה לאופן שעשויה לשמש פונקציה, אתה יכול להשתמש בביטוי רגיל למצוא שפונקציה נמצא בשימוש בכל מיני מקרים שונים. אתה יכול לחפש fwrite, ואז אתה יכול לחפש את הדגל של לכתוב או לקרוא אם אתה רוצה דוגמה לfwrite בשימוש במקרה זה. אז אותו הדבר שם, והנה כמה המלצות. זה יהיה זמין באינטרנט, כמו גם, אז הולך קדימה אם אתה רוצה להסתכל על פייתון, grep, פרל - אתה רק רוצה לקבל קצת השראה או אם אתה רוצה להסתכל יותר בתאוריה הנה כמה קפיצות טובות את המקומות. תודה רבה. [CS50.TV]