הבה נמשיך את המחקר שלנו על ביטויים רגולריים. במאמר זה נבחן מחלקות תווים מוגדרות מראש וכן כימות (חיפוש רצפים).
כיתות תווים מוגדרות מראש
ה-API של המחלקהPattern
מכיל מחלקות תווים מוגדרות מראש המציעות קיצורי דרך נוחים לביטויים רגולריים נפוצים. בטבלה זו, המבנים בעמודה השמאלית הם ייצוגים קצרים של הביטויים בעמודה הימנית. לדוגמה, \d
פירושו מספר (0-9), \w
פירושו כל אות גדולה או קטנה, קו תחתון או מספר. השתמש במחלקות תווים מוגדרות מראש במידת האפשר. זה יקל על קריאת הקוד שלך ותתקן שגיאות. קונסטרוקטים שמתחילים עם קו נטוי אחור נקראים בריחה או מוגנת. במאמרים קודמים כבר דיברנו על בריחה מתווים מיוחדים עם נטוי או סמלים \Q
ושימוש \E
בהם כתווים רגילים. אם אתה משתמש באלכסון אחורי עם תווים רגילים (מילוליים), אז אתה צריך להימלט מהלוכסן האחורי כדי שהביטוי יקמפל.
private final String REGEX = "\\d"; // цифра
בדוגמה זו \d
, ביטוי רגולרי; הנטוי הנוסף הוא הכרחי כדי שהתוכנית תוכל להדר. תוכנית הבדיקה שלנו קוראת ביטויים רגולריים ישירות מהמסוף, כך שאין צורך בקו נטוי נוסף. הדוגמה הבאה מדגימה את השימוש במחלקות תווים מוגדרות מראש: בשלוש הדוגמאות הראשונות, הביטוי הרגולרי הוא פשוט " .
" (התו המיוחד הנקודה), שפירושו כל תו. לפיכך, החיפוש הצליח בכל המקרים. דוגמאות אחרות משתמשות במחלקות תווים מוגדרות מראש, שמשמעויותיהן דנו בטבלה למעלה.
מכמתים
מכמתים מאפשרים לך לציין את מספר המופעים של תו במחרוזת. בואו נסתכל מקרוב על המורכבויות של האופן שבו מכמתים חמדניים, עצלנים ומאוד חמדנים עובדים. במבט ראשון אולי נראה שהכמתים X?, X?? ו-X?+ פועלים באותה צורה: "X נוכח פעם אחת או בכלל לא." ישנם הבדלים קלים ביישום מכמתים אלה, עליהם נסתכל להלן.התאמות באורך אפס
נתחיל עם החמדן. בוא נכתוב שלושה ביטויים רגולריים שונים: האות "a" עם תווים מיוחדים ?, * או +. בוא נראה מה קורה אם נבדוק את הביטויים הרגולריים האלה בשורה ריקה: בדוגמה למעלה, החיפוש הצליח בשני המקרים הראשונים, כי הביטויים a? ו-a* מאפשרים לתו a להיות חסר במחרוזת. שים לב גם שמדד ההתחלה וההתאמה האחרונה זהים (0). מכיוון שלמחרוזת הקלט אין אורך, התוכנית לא מוצאת כלום :) במיקום הראשון. מקרה זה נקרא התאמה באורך אפס. התאמות כאלה מתרחשות במספר מקרים: כאשר שורת הקלט ריקה, בתחילת שורת הקלט, אחרי התו האחרון של השורה, או בין תווים בשורה. קל לזהות משחקים באורך אפס: הם מתחילים ומסתיימים באותה עמדה. בואו נסתכל על עוד כמה דוגמאות של התאמות באורך אפס. בואו נחקור התאמות באורך אפס עם כמה דוגמאות נוספות. הבה נשנה את מחרוזת הקלט לתו "a" ונצפה באפקט מעניין: כל שלושת המכמתים מצאו את התו "a", אך השניים הראשונים, המאפשרים היעדר תו, מצאו התאמה באורך אפס במיקום 1 - אחרי התו האחרון של המחרוזת. זה קורה כי התוכנית מתייחסת לדמות "a" כמחרוזת ו"רצה" דרכה עד שאין יותר התאמות. בהתאם לכמת המשמש, התוכנית תמצא או לא תמצא "כלום" בסוף המחרוזת. כעת נשנה את מחרוזת הקלט לרצף של חמש אותיות "a": ביטוי רגולרי a? מוצא התאמה לכל אות במחרוזת בנפרד. הביטוי a* מוצא שתי התאמות: רצף התווים "a"' והתאמה באורך אפס במיקום 5. ולבסוף, הביטוי הרגיל a+ מוצא רק את רצף התווים "a", מבלי למצוא "כלום" :) מה יקרה אם תינתן מחרוזת המכילה תווים שונים כקלט? לדוגמה, "ababaaaab": התו "b" נמצא בעמדות 1, 3 ו-8 והתוכנית מוצאת התאמות באורך אפס במיקומים אלה. ביטוי רגולרי א? לא שם לב ל"ב", אלא פשוט מחפש את נוכחותה (או היעדר) של הדמות "א". אם המכמת מאפשר היעדר "a", כל התווים במחרוזת מלבד "a" יוצגו כהתאמה באורך אפס. כדי למצוא רצפים באורך נתון, פשוט ציין את האורך בסוגריים מסולסלים: הביטוי הרגולרי a{3} מחפש רצף של שלושה תווים "a". שום דבר לא נמצא בשורה הראשונה כי לא היו מספיק א'ים בשורה. השני מכיל 3 תווים, שהתוכנית מוצאת. המבחן השלישי גם מוצא התאמה בתחילת המחרוזת. כל מה שאחרי התו השלישי לא עונה על הביטוי הרגולרי, בקוד שלמטה זה כן ויהיו מספר התאמות: כדי לציין את אורך הרצף המינימלי, השתמשו ב:Enter your regex: a{3,}
Enter input string to search: aaaaaaaaa
I found the text "aaaaaaaaa" starting at index 0 and ending at index 9.
בדוגמה זו, התוכנית מוצאת רק התאמה אחת מכיוון שהמחרוזת עומדת בדרישת אורך הרצף המינימלי של (3) תווים "a". לבסוף, הגדרת אורך הרצף המרבי: בדוגמה זו, ההתאמה הראשונה הסתיימה בתו השישי. ההתאמה השנייה מכילה תווים אחרי השישית, כי הם עומדים בדרישת האורך המינימלי. אם המחרוזת הייתה קצרה בתו אחד, לא הייתה התאמה שנייה.
GO TO FULL VERSION