JavaRush /בלוג Java /Random-HE /יסודות של ביטויים רגולריים ב-Java. חלק 3
articles
רָמָה

יסודות של ביטויים רגולריים ב-Java. חלק 3

פורסם בקבוצה
הבה נמשיך את המחקר שלנו על ביטויים רגולריים. במאמר זה נבחן מחלקות תווים מוגדרות מראש וכן כימות (חיפוש רצפים). יסודות של ביטויים רגולריים ב-Java.  חלק 3 - 1

כיתות תווים מוגדרות מראש

ה-API של המחלקה Patternמכיל מחלקות תווים מוגדרות מראש המציעות קיצורי דרך נוחים לביטויים רגולריים נפוצים. יסודות של ביטויים רגולריים ב-Java.  חלק 3 - 2בטבלה זו, המבנים בעמודה השמאלית הם ייצוגים קצרים של הביטויים בעמודה הימנית. לדוגמה, \dפירושו מספר (0-9), \wפירושו כל אות גדולה או קטנה, קו תחתון או מספר. השתמש במחלקות תווים מוגדרות מראש במידת האפשר. זה יקל על קריאת הקוד שלך ותתקן שגיאות. קונסטרוקטים שמתחילים עם קו נטוי אחור נקראים בריחה או מוגנת. במאמרים קודמים כבר דיברנו על בריחה מתווים מיוחדים עם נטוי או סמלים \Qושימוש \Eבהם כתווים רגילים. אם אתה משתמש באלכסון אחורי עם תווים רגילים (מילוליים), אז אתה צריך להימלט מהלוכסן האחורי כדי שהביטוי יקמפל.
private final String REGEX = "\\d"; // цифра
בדוגמה זו \d, ביטוי רגולרי; הנטוי הנוסף הוא הכרחי כדי שהתוכנית תוכל להדר. תוכנית הבדיקה שלנו קוראת ביטויים רגולריים ישירות מהמסוף, כך שאין צורך בקו נטוי נוסף. הדוגמה הבאה מדגימה את השימוש במחלקות תווים מוגדרות מראש: יסודות של ביטויים רגולריים ב-Java.  חלק 3 - 3יסודות של ביטויים רגולריים ב-Java.  חלק 3 - 4בשלוש הדוגמאות הראשונות, הביטוי הרגולרי הוא פשוט " ." (התו המיוחד הנקודה), שפירושו כל תו. לפיכך, החיפוש הצליח בכל המקרים. דוגמאות אחרות משתמשות במחלקות תווים מוגדרות מראש, שמשמעויותיהן דנו בטבלה למעלה.

מכמתים

יסודות של ביטויים רגולריים ב-Java.  חלק 3 - 4מכמתים מאפשרים לך לציין את מספר המופעים של תו במחרוזת. בואו נסתכל מקרוב על המורכבויות של האופן שבו מכמתים חמדניים, עצלנים ומאוד חמדנים עובדים. במבט ראשון אולי נראה שהכמתים X?, X?? ו-X?+ פועלים באותה צורה: "X נוכח פעם אחת או בכלל לא." ישנם הבדלים קלים ביישום מכמתים אלה, עליהם נסתכל להלן.

התאמות באורך אפס

נתחיל עם החמדן. בוא נכתוב שלושה ביטויים רגולריים שונים: האות "a" עם תווים מיוחדים ?, * או +. בוא נראה מה קורה אם נבדוק את הביטויים הרגולריים האלה בשורה ריקה: יסודות של ביטויים רגולריים ב-Java.  חלק 3 - 5בדוגמה למעלה, החיפוש הצליח בשני המקרים הראשונים, כי הביטויים a? ו-a* מאפשרים לתו a להיות חסר במחרוזת. שים לב גם שמדד ההתחלה וההתאמה האחרונה זהים (0). מכיוון שלמחרוזת הקלט אין אורך, התוכנית לא מוצאת כלום :) במיקום הראשון. מקרה זה נקרא התאמה באורך אפס. התאמות כאלה מתרחשות במספר מקרים: כאשר שורת הקלט ריקה, בתחילת שורת הקלט, אחרי התו האחרון של השורה, או בין תווים בשורה. קל לזהות משחקים באורך אפס: הם מתחילים ומסתיימים באותה עמדה. בואו נסתכל על עוד כמה דוגמאות של התאמות באורך אפס. בואו נחקור התאמות באורך אפס עם כמה דוגמאות נוספות. הבה נשנה את מחרוזת הקלט לתו "a" ונצפה באפקט מעניין: יסודות של ביטויים רגולריים ב-Java.  חלק 3 - 6כל שלושת המכמתים מצאו את התו "a", אך השניים הראשונים, המאפשרים היעדר תו, מצאו התאמה באורך אפס במיקום 1 - אחרי התו האחרון של המחרוזת. זה קורה כי התוכנית מתייחסת לדמות "a" כמחרוזת ו"רצה" דרכה עד שאין יותר התאמות. בהתאם לכמת המשמש, התוכנית תמצא או לא תמצא "כלום" בסוף המחרוזת. כעת נשנה את מחרוזת הקלט לרצף של חמש אותיות "a": יסודות של ביטויים רגולריים ב-Java.  חלק 3 - 7ביטוי רגולרי a? מוצא התאמה לכל אות במחרוזת בנפרד. הביטוי a* מוצא שתי התאמות: רצף התווים "a"' והתאמה באורך אפס במיקום 5. ולבסוף, הביטוי הרגיל a+ מוצא רק את רצף התווים "a", מבלי למצוא "כלום" :) מה יקרה אם תינתן מחרוזת המכילה תווים שונים כקלט? לדוגמה, "ababaaaab": יסודות של ביטויים רגולריים ב-Java.  חלק 3 - 8התו "b" נמצא בעמדות 1, 3 ו-8 והתוכנית מוצאת התאמות באורך אפס במיקומים אלה. ביטוי רגולרי א? לא שם לב ל"ב", אלא פשוט מחפש את נוכחותה (או היעדר) של הדמות "א". אם המכמת מאפשר היעדר "a", כל התווים במחרוזת מלבד "a" יוצגו כהתאמה באורך אפס. כדי למצוא רצפים באורך נתון, פשוט ציין את האורך בסוגריים מסולסלים: יסודות של ביטויים רגולריים ב-Java.  חלק 3 - 9הביטוי הרגולרי a{3} מחפש רצף של שלושה תווים "a". שום דבר לא נמצא בשורה הראשונה כי לא היו מספיק א'ים בשורה. השני מכיל 3 תווים, שהתוכנית מוצאת. המבחן השלישי גם מוצא התאמה בתחילת המחרוזת. כל מה שאחרי התו השלישי לא עונה על הביטוי הרגולרי, בקוד שלמטה זה כן ויהיו מספר התאמות: יסודות של ביטויים רגולריים ב-Java.  חלק 3 - 10כדי לציין את אורך הרצף המינימלי, השתמשו ב:
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". לבסוף, הגדרת אורך הרצף המרבי: יסודות של ביטויים רגולריים ב-Java.  חלק 3 - 11בדוגמה זו, ההתאמה הראשונה הסתיימה בתו השישי. ההתאמה השנייה מכילה תווים אחרי השישית, כי הם עומדים בדרישת האורך המינימלי. אם המחרוזת הייתה קצרה בתו אחד, לא הייתה התאמה שנייה.

שימוש בקבוצות תווים ומחלקות עם מכמות

עד לנקודה זו, בדקנו מכמתים על מחרוזות המכילות את אותו תו. מכמתים חלים רק על תו בודד, כך שהביטוי הרגולרי "abc+" יתאים למחרוזות המכילות "ab" ו-"c" פעם אחת או יותר. זה לא אומר "abc" פעם אחת או יותר. אבל ניתן להשתמש בכימות בשילוב עם קבוצות ומחלקות תווים, כגון [abc]+ (a או b או c, פעם אחת או יותר) או (abc)+ ("abc" פעם אחת או יותר). בוא נמצא קבוצת דמויות (כלב), שלוש פעמים בשורה: יסודות של ביטויים רגולריים ב-Java.  חלק 3 - 12בדוגמה הראשונה, התוכנית מוצאת התאמה, כי הכמת משתרע לקבוצת תווים. אם תסיר את הסוגריים, הכמת {3} יחול רק על האות "g". אתה יכול גם להשתמש במכמתים עם מחלקות תווים: Основы регулярных выражений в Java. Часть 3 - 13המכמת {3} חל על מחלקת התווים בסוגריים בדוגמה הראשונה, ובשנייה - רק על התו "c".

הבדלים בין חמדנים, עצלנים וחמדנים יתר על המידה

ישנם הבדלים קלים בין מכמתים חמדנים, סרבנים ורכושניים. מכמים חמדנים נקראים כך מכיוון שהם מנסים למצוא את ההתאמה הארוכה ביותר האפשרית: התוכנית תחילה מנסה "לאכול" את כל המחרוזת, אם לא נמצא התאמה, אז תו אחד נמחק והחיפוש חוזר על עצמו עד שנמצא התאמה או לא נשארו עוד דמויות. עצלנים, לעומת זאת, מתחילים בתחילת השורה, מוסיפים דמות אחר דמות עד שהם מוצאים התאמה. לבסוף, כימות קנאי סורק את כל המחרוזת פעם אחת, מבלי להסיר תווים כמו בחמדן. להדגמה, נשתמש במחרוזת xfooxxxxxxxfoo. Основы регулярных выражений в Java. Часть 3 - 14הדוגמה הראשונה משתמשת בכמת חמד .* כדי למצוא כל תו, 0 פעמים או יותר, ואחריו התווים "f" "o" "o". מכיוון שהמחטב הוא חמדן, ההתאמה שנמצאה מכילה את כל המחרוזת. מכמת חמדן לא ימצא את כל ההתאמות במחרוזת מכיוון בשלב הראשון, לאחר סריקת המחרוזת כולה, הוא ימצא התאמה ויסיים את העבודה. הדוגמה השנייה היא עצלנית ומתחילה מתחילת השורה, ומוסיפה תו אחר תו. התוכנית מתחילה בבדיקת "ריקנות", אך מאז הרצף "foo" אינו בתחילת השורה, החיפוש ממשיך עם הוספת התו "x", ולאחר מכן תימצא ההתאמה הראשונה בין המדדים 0 ו-4. החיפוש נמשך עד סוף השורה וההתאמה השנייה תימצא בין המדדים 4 ל-13. הדוגמה השלישית לא מוצאת צירופי מקרים מכיוון שהכמת מקנא. במקרה זה, הביטוי הרגולרי .*+ "אכל" את כל השורה, ולא משאיר דבר עבור "foo". השתמש בכמת הקנאי כאשר אתה צריך להשליך כל דבר מיותר במחרוזת, זה יהיה יעיל יותר מהכמת החמדן המקביל. זה הכל! קישור למקור: יסודות הביטויים הרגולריים ב-Java. חלק 3
הערות
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION