JavaRush /בלוג Java /Random-HE /RegEx: 20 צעדים קצרים לשליטה בביטויים רגולריים. חלק 4
Artur
רָמָה
Tallinn

RegEx: 20 צעדים קצרים לשליטה בביטויים רגולריים. חלק 4

פורסם בקבוצה
RegEx: 20 צעדים קצרים לשליטה בביטויים רגולריים. חלק 1 RegEx: 20 צעדים קצרים לשליטה בביטויים רגולריים. חלק ב' 20 צעדים קצרים לשליטה בביטויים רגולריים. חלק 3 החלק האחרון הזה, באמצע, יגע בדברים המשמשים בעיקר מאסטרים לביטוי רגולרי. אבל החומר מהחלקים הקודמים היה לך קל, נכון? זה אומר שאתה יכול להתמודד עם החומר הזה באותה קלות! מקור כאן RegEx: 20 צעדים קצרים לשליטה בביטויים רגולריים.  חלק 4 - 1 <h2>שלב 16: קבוצות ללא לכידה (?:)</h2> RegEx: 20 צעדים קצרים לשליטה בביטויים רגולריים.  חלק 4 - 2בשתי הדוגמאות בשלב הקודם, תפסנו טקסט שלא באמת היינו צריכים. במשימה File Sizes, תפסנו את הרווחים לפני הספרה הראשונה של גדלי הקבצים, ובמטלת CSV, תפסנו את הפסיקים בין כל אסימון. אנחנו לא צריכים ללכוד את הדמויות האלה, אבל אנחנו צריכים להשתמש בהן כדי לבנות את הביטוי הרגולרי שלנו. אלו הן אפשרויות אידיאליות לשימוש בקבוצה מבלי ללכוד, (?:). קבוצה שאינה לוכדת עושה בדיוק מה שהיא נשמעת - היא מאפשרת לקבץ תווים ולהשתמש בהם בביטויים רגולריים, אבל לא לוכדת אותם בקבוצה ממוספרת:
pattern: (?:")([^"]+)(?:") 
string: אני רוצה רק "הטקסט בתוך המרכאות האלה" .
תואמים:             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
קבוצה:                 1111111111111111111111111111    
( דוגמה ) הביטוי הרגולרי תואם כעת את הטקסט המצוטט כמו גם את תווי המירכאות עצמם, אך קבוצת הלכידה תפסה רק את הטקסט המצוטט. מדוע עלינו לעשות זאת? הנקודה היא שרוב מנועי הביטוי הרגולרי מאפשרים לך לשחזר טקסט מקבוצות לכידה המוגדרות בביטויים הרגולריים שלך. אם נוכל לחתוך את התווים הנוספים שאנחנו לא צריכים מבלי לכלול אותם בקבוצות הלכידה שלנו, זה יקל על הניתוח ותמרן הטקסט מאוחר יותר. הנה איך לנקות את מנתח ה-CSV מהשלב הקודם:
דפוס: (?:^|,)\s*(?:\"([^",]*)\"|([^", ]*)) 
מחרוזת:   a , " b ", " cd ", e , f , " gh ", dfgi ,, k , "", l 
תואם: ^ ^ ^^^ ^ ^ ^^^ ^^^^ ^ ^ 
קבוצה:    2 1 111 2 2 111 2222 2 2    
( דוגמה ) יש כמה דברים ש<mark>שים לב כאן:</mark> ראשית, אנחנו כבר לא מצלמים פסיקים מכיוון ששינינו את קבוצת הלכידה (^|,)לקבוצה שאינה לוכדת (?:^|,). שנית, קינן את קבוצת הלכידה בתוך קבוצת הלא לכידה. זה שימושי כאשר, למשל, אתה צריך שקבוצת תווים תופיע בסדר מסוים, אבל אכפת לך רק מקבוצת משנה של התווים האלה. במקרה שלנו, היינו צריכים תווים שאינם מרכאות ולא[^",]* פסיקים שיופיעו במרכאות, אבל למעשה לא היינו צריכים את תווי המירכאות עצמם, כך שלא היה צורך ללכוד אותם. לבסוף, <mark>שים לב</mark> שבדוגמה למעלה יש גם התאמה באורך אפס בין התווים kו- l. המירכאות ""הן המחרוזת המשנה שחיפשה, אך אין תווים בין המירכאות, כך שמחרוזת המשנה התואמת אינה מכילה תווים (אורך אפס). <h3>האם נאחד את הידע שלנו? להלן שתי משימות וחצי שיעזרו לנו בכך:</h3> שימוש בקבוצות שאינן לוכדות (וקבוצות לכידה, ומחלקות תווים וכו'), כתוב ביטוי רגולרי שלוכד רק גדלי קבצים מעוצבים כהלכה על הקו למטה:
תבנית:
מחרוזת:   6.6KB 1..3KB 12KB 5G 3.3MB KB .6.2TB 9MB .
תואמים: ^^^^^ ^^^^^ ^^^^^^ ^^^^ 
קבוצה:    11111 1111 11111 111    
( פתרון ) תגיות פתיחה של HTML מתחילות ב- <ומסתיימות ב- >. תגי סגירת HTML מתחילים ברצף של תווים </ומסתיימים בתו >. שם התג כלול בין התווים הללו. האם אתה יכול לכתוב ביטוי רגולרי כדי ללכוד רק את השמות בתגים הבאים? (ייתכן שתוכל לפתור בעיה זו מבלי להשתמש בקבוצות שאינן לוכדות. נסה לפתור זאת בשתי דרכים! פעם אחת עם קבוצות ופעם אחת בלי.)
תבנית:
מחרוזת:   <p> </span> <div> </kbd> <link> 
תואמת: ^^^ ^^^^^^ ^^^^^ ^^^^^^ ^^^^^^ 
קבוצה:    1 1111 111 111 1111    
( פתרון באמצעות קבוצות שאינן לוכדות ) ( פתרון ללא שימוש בקבוצות שאינן לוכדות ) <h2>שלב 17: קישורים נכנסים \Nוקבוצות לכידה בשמות</h2> RegEx: 20 צעדים קצרים לשליטה בביטויים רגולריים.  חלק 4 - 3למרות שהזהרתי אותך במבוא שניסיון ליצור מנתח HTML באמצעות ביטויים רגולריים בדרך כלל מוביל לכאב לב, הדוגמה האחרונה הזו היא דוגמה נחמדה לתכונה שימושית נוספת (לפעמים) של רוב הביטויים הרגולריים: הפניות לאחור. קישורים נכנסים הם כמו קבוצות חוזרות שבהן אתה יכול לנסות ללכוד את אותו טקסט פעמיים. אבל הם נבדלים בהיבט אחד חשוב - הם ילכדו רק את אותו טקסט, דמות אחר דמות. בעוד שקבוצה חוזרת תאפשר לנו ללכוד משהו כזה:
תבנית: (he(?:[az])+) 
מחרוזת:   heyabcdefg hey heyo heyellow heyyyyyyyyy 
תואמים: ^^^^^^^^^^ ^^^ ^^^^ ^^^^^^^^^^^^ ^^^^^^^^ 
קבוצה:    1111111111 111 1111 11111111 11111111111    
( דוגמה ) ... אז הקישור האחורי יתאים רק לזה:
תבנית: (he([az])(\2+)) 
מחרוזת: heyabcdefg hey heyo heyellow heyyyyyyyyy 
התאמות:                              ^^^^^^^^^^^^ 
קבוצה:                                 11233333333    
( דוגמה ) קבוצות לכידה חוזרות שימושיות כאשר אתה רוצה להתאים את אותו דפוס שוב ושוב, בעוד שקישורים נכנסים טובים כאשר אתה רוצה להתאים את אותו טקסט. לדוגמה, נוכל להשתמש ב-backlink כדי לנסות למצוא תגיות HTML פתיחה וסגירה תואמות:
תבנית: <(\w+)[^>]*>[^<]+<\/\1> 
מחרוזת:   <span style="color: red">היי</span> 
תואמת: ^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
קבוצה:    1111    
( דוגמה ) <mark>שים לב</mark> כי זוהי דוגמה פשוטה ביותר ואני ממליץ בחום לא לנסות לכתוב מנתח HTML מבוסס ביטוי רגולרי. זהו תחביר מורכב מאוד וסביר להניח שיעשה אותך חולה. קבוצות לכידה בשמות דומות מאוד לקישורים נכנסים, אז אני אכסה אותן בקצרה כאן. ההבדל היחיד בין הפניות לאחור לקבוצת לכידה עם שם הוא ש... לקבוצת לכידה עם שם יש שם:
דפוס: <(?<tag>\w+)[^>]*>[^<]+<\/(?P=tag)></tag> 
מחרוזת:   <span style="color: red">היי< /span> 
תואם: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
קבוצה:    1111    
( דוגמה ) אתה יכול ליצור קבוצת לכידה בשם באמצעות תחביר (?<name>...) או (?'name'...) (ביטוי רגולרי תואם.NET) או עם תחביר זה (?P<name>. ..) או (?P'name'...) (ביטוי רגולרי תואם פייתון). מכיוון שאנו משתמשים ב-PCRE (Perl Compatible Regular Expression) התומך בשתי הגרסאות, אנו יכולים להשתמש באחת מהן כאן. (Java 7 העתיק את תחביר NET, אבל רק את גרסת סוגריים זווית. הערת המתרגם) כדי לחזור על קבוצת לכידה עם שם מאוחר יותר בביטוי רגולרי, אנו משתמשים ב-\<kname> או \k'name' (.NET) או (? P= שם) (Python). שוב, PCRE תומך בכל האפשרויות השונות הללו. אתה יכול לקרוא עוד על קבוצות לכידה בשם כאן , אבל זה היה רוב מה שאתה באמת צריך לדעת עליהם. <h3>משימה לעזור לנו:</h3> השתמש בקישורים נכנסים כדי לעזור לי לזכור... אמממ... את שמו של האדם הזה.
תבנית:
string: "היי שמי ג'ו." [מאוחר יותר] "איך קוראים לבחור הזה? ג'ו ?"
תואמים:        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^ 
קבוצה:                  111    
( פתרון ) <h2>שלב 18: מבט קדימה והסתכל מאחור</h2> RegEx: 20 צעדים קצרים לשליטה בביטויים רגולריים.  חלק 4 - 4כעת נצלול לכמה מהתכונות המתקדמות של ביטויים רגולריים. אני משתמש בכל דבר עד שלב 16 לעתים קרובות למדי. אבל הצעדים האחרונים האלה מיועדים רק לאנשים שמשתמשים ברצינות רבה מאוד ב-Regex כדי להתאים ביטויים מורכבים מאוד. במילים אחרות, מאסטרים של ביטויים רגולריים. "להסתכל קדימה" ו"להסתכל אחורה" אולי נראים מסובכים למדי, אבל הם באמת לא מסובכים מדי. הם מאפשרים לך לעשות משהו דומה למה שעשינו עם קבוצות שאינן לוכדות קודם לכן - בדוק אם יש טקסט כלשהו מיד לפני או מיד אחרי הטקסט האמיתי שאנו רוצים להתאים. לדוגמה, נניח שאנחנו רוצים להתאים רק את השמות של דברים שאנשים אוהבים, אבל רק אם הם מתלהבים מזה (רק אם הם מסיימים את המשפט שלהם בסימן קריאה). נוכל לעשות משהו כמו:
תבנית: (\w+)(?=!) 
מחרוזת: אני אוהב שולחן עבודה. אני מעריך מהדק. אני אוהב מנורה !
התאמות:                                           ^^^^ 
קבוצה:                                              1111    
( דוגמה ) אתה יכול לראות כיצד קבוצת הלכידה לעיל (\w+), שבדרך כלל מתאימה לכל אחת מהמילים בקטע, מתאימה רק למילה מנורה. מבט חיובי קדימה (?=!)אומר שאנחנו יכולים להתאים רק רצפים שמסתיימים !אבל אנחנו לא מתאימים למעשה לתו של סימן הקריאה עצמו. זוהי הבחנה חשובה מכיוון שעם קבוצות שאינן תופסות אנו מתאימים את הדמות אך לא לוכדים אותה. בהסתכלות קדימה ובמבט לאחור, אנו משתמשים בדמות כדי לבנות את הביטוי הקבוע שלנו, אבל אז אנחנו אפילו לא מתאימים אותה לעצמה. נוכל להתאים אותו מאוחר יותר בביטוי הרגולרי שלנו. ישנם ארבעה סוגים של מבט-אחור ומבט לאחור: מבט חיובי (?=...), מבט שלילי (?!...), מבט חיובי (?<=...) ומבט שלילי (?<!. ..) . הם עושים מה שהם נשמעים - מבט חיובי ומבט לאחור מאפשרים למנוע הביטויים הרגולריים להמשיך להתאים רק כאשר הטקסט הכלול במבט לאחור באמת תואם. מבט שלילי ו-lookbehind עושים את ההיפך - הם מאפשרים להתאים את ה-regex רק כאשר הטקסט הכלול ב-lookahead/lookbehind אינו תואם. לדוגמה, אנו רוצים להתאים את שמות השיטה רק בשרשרת של רצפי מתודות, לא לאובייקט שהם פועלים עליו. במקרה זה, יש להקדים את כל שם שיטה ב- .. ביטוי רגולרי באמצעות מבט פשוט לאחור יכול לעזור כאן:
תבנית: (?<=\.)(\w+) 
מחרוזת: myArray. flatMap.aggregate.summarise.print !
תואמים:         ^^^^^^^ ^^^^^^^^^ ^^^^^^^^^ ^^^^^ 
קבוצה:            1111111 111111111 111111111 11111    
( דוגמה ) בטקסט שלמעלה, אנו מתאימים לכל רצף של תווי מילה \w+, אך רק אם לפניהם התו .. נוכל להשיג משהו דומה באמצעות קבוצות שאינן לוכדות, אבל התוצאה קצת יותר מבולגנת:
תבנית: (?:\.)(\w+) 
מחרוזת: myArray .flatMap.aggregate.summarise.print !
תואמים:        ^^^^^^^^ ^^^^^^^^^ ^^^^^^^^^ ^^^^^ 
קבוצה:            1111111 111111111 111111111 11111    
( דוגמה ) למרות שהוא קצר יותר, הוא תואם תווים שאנחנו לא צריכים. אמנם הדוגמה הזו עשויה להיראות טריוויאלית, אבל מבט קדימה והסתכלות לאחור יכולים באמת לעזור לנו לנקות את הביטויים הקבועים שלנו. <h3>נותרו מעט מאוד עד לסיום! 2 המשימות הבאות יקרבו אותנו צעד אחד אליו:</h3> מבט שלילי (?<!...) מאפשר למנוע הביטוי הרגולרי להמשיך ולנסות למצוא התאמה רק אם הטקסט הכלול בתוך המראה השלילי מאחור אינו מוצג עד לשאר הטקסט , איתו אתה צריך למצוא התאמה. לדוגמה, נוכל להשתמש בביטוי רגולרי כדי להתאים רק לשמות המשפחה של נשים המשתתפות בכנס. לשם כך, ברצוננו לוודא ששם משפחתו של האדם אינו קדום ב- Mr.. האם אתה יכול לכתוב ביטוי רגולרי עבור זה? (ניתן להניח ששמות משפחה הם באורך של לפחות ארבעה תווים.)
תבנית:
מחרוזת: מר. בראון, גב' סמית' , גברת. ג'ונס , מיס דייזי , מר. ירוק
תואמים:                ^^^^^ ^^^^^ ^^^^^ 
קבוצה:                   11111 11111 11111    
( פתרון ) נניח שאנחנו מנקים מסד נתונים ויש לנו עמודת מידע שמייצגת אחוזים. למרבה הצער, חלק מהאנשים כתבו מספרים כערכים עשרוניים בטווח [0.0, 1.0], בעוד שאחרים כתבו אחוזים בטווח [0.0%, 100.0%], ואחרים כתבו ערכי אחוזים. אבל שכחו את הסימן האחוז המילולי %. באמצעות מבט שלילי (?!...), האם אתה יכול לסמן רק את הערכים שצריכים להיות אחוזים אך חסרים בהם ספרות %? אלה חייבים להיות ערכים שגדולים בהחלט מ-1.00, אך ללא נגרר %. (אף מספר לא יכול להכיל יותר משתי ספרות לפני או אחרי הנקודה העשרונית.) <mark>שים לב</mark> שפתרון זה הוא קשה ביותר . אם אתה יכול לפתור בעיה זו מבלי להסתכל על התשובה שלי, אז כבר יש לך כישורים עצומים בביטויים רגולריים!
תבנית:
מחרוזת: 0.32 100.00 5.6 0.27 98% 12.2% 1.01 0.99% 0.99 13.13 1.10 
התאמות:      ^^^^^^ ^^^ ^^^^ ^^^^^ ^^^^ 
קבוצה:         111111111111111111    
( פתרון ) <h2>שלב 19: תנאים בביטויים רגולריים</h2> RegEx: 20 צעדים קצרים לשליטה בביטויים רגולריים.  חלק 4 - 5כעת הגענו לנקודה שבה רוב האנשים לא ישתמשו יותר בביטויים רגולריים. כיסינו כנראה 95% ממקרי השימוש בביטויים רגולריים פשוטים, וכל מה שנעשה בשלבים 19 ו-20 נעשה בדרך כלל על ידי שפת מניפולציה של טקסט מלא יותר כמו awk או sed (או שפת תכנות למטרות כלליות). עם זאת, בואו נמשיך הלאה, רק שתדעו מה ביטוי רגולרי באמת יכול לעשות. למרות שביטויים רגולריים אינם שלמים של Turing , חלק ממנועי ביטוי רגולרי מציעים תכונות הדומות מאוד לשפת תכנות שלמה. תכונה אחת כזו היא "מצב". התנאים הרגולריים מאפשרים הצהרות if-then-else, כאשר הענף הנבחר נקבע על ידי ה"מבט קדימה" או "הסתכל אחורה" שלמדנו עליו בשלב הקודם. לדוגמה, ייתכן שתרצה להתאים רק ערכים חוקיים ברשימת תאריכים:
תבנית: (?<=פברואר )([1-2][0-9])|(?<=מרץ )([1-2][0-9]|3[0-1]) 
מחרוזת: תאריכי עבודה : 28 בפברואר , 29 בפברואר , 30 בפברואר, 30 במרץ , 31 במרץ  
התאמות:                   ^^ ^^ ^^ ^^ 
קבוצה:                      11 11 22 22    
( דוגמה ) <mark>שים לב</mark> שגם הקבוצות שלעיל מתווספות לפי חודש. נוכל לכתוב ביטוי רגולרי עבור כל 12 החודשים וללכוד רק תאריכים תקפים, שלאחר מכן ישולבו לקבוצות באינדקס לפי חודש בשנה. האמור לעיל משתמש במעין מבנה דמוי אם שיחפש התאמות רק בקבוצה הראשונה אם "פברואר" מקדים מספר (ובדומה לשנייה). אבל מה אם היינו רוצים להשתמש רק בעיבוד מיוחד לפברואר? משהו כמו "אם לפני המספר מופיע "פברואר", עשה זאת, אחרת עשה דבר אחר. הנה איך תנאים עושים את זה:
דפוס: (?(?<=פברואר )([1-2][0-9])|([1-2][0-9]|3[0-1])) 
מחרוזת: תאריכי עבודה: 28 בפברואר , 29 בפברואר , 30 בפברואר, 30 במרץ , 31 במרץ  
התאמות:                   ^^ ^^ ^^ ^^ 
קבוצה:                      11 11 22 22    
( דוגמה ) המבנה if-then-else נראה כמו (?(If)then|else), כאשר (if) מוחלף ב"מבט קדימה" או "הסתכל אחורה". בדוגמה שלמעלה, (אם) נכתב כ (?<=Feb). אתה יכול לראות שהתאמנו תאריכים גדולים מ-29, אבל רק אם הם לא עקבו אחר "פברואר". שימוש ב-lookbehind בביטויים מותנים שימושי אם ברצונך להבטיח שההתאמה קודמת לטקסט כלשהו. תנאי מבט חיובי יכולים להיות מבלבלים מכיוון שהתנאי עצמו אינו תואם לאף טקסט. אז אם אתה רוצה שלתנאי if יהיה אי פעם ערך, הוא חייב להיות בר השוואה למבט קדימה כמו להלן:
דפוס: (?(?=exact)exact|else)wo 
מחרוזת: exact else exactwo elsewo  
התאמות:            ^^^^^^^ ^^^^^^
( דוגמה ) משמעות הדבר היא שתנאי מבט חיובי הם חסרי תועלת. אתה בודק כדי לראות אם הטקסט הזה נמצא מקדימה ואז מספקים דפוס תואם כדי לעקוב אחריו. הביטוי המותנה לא עוזר לנו כאן בכלל. אתה יכול גם פשוט להחליף את האמור לעיל בביטוי רגולרי פשוט יותר:
דפוס: (?:exact|else)wo 
מחרוזת: exact else exactwo elsewo  
התאמות:            ^^^^^^^ ^^^^^^
( דוגמה ) אז, כלל האצבע לביטויים מותנים הוא: מבחן, מבחן ושוב מבחן. אחרת, פתרונות שאתה חושב שהם ברורים ייכשלו בדרכים המרגשות והבלתי צפויות ביותר :) <h3>הנה הגענו לגוש המשימות האחרון שמפריד בינינו לבין השלב ה-20 האחרון:</h3> כתוב ביטוי רגולרי ש משתמש בביטוי מותנה מבט שלילי כדי לבדוק אם המילה הבאה מתחילה באות גדולה. אם כן, קח רק אות גדולה אחת ולאחר מכן את האותיות הקטנות. אם לא, קח כל תווי מילה.
תבנית:
מחרוזת:   Jones Smith 9sfjn Hobbes 23r4tgr9h CSV Csv vVv 
התאמות: ^^^^^ ^^^^^ ^^^^^ ^^^^^^ ^^^^^^^^^^^^ ^^^ 
קבוצה:    22222 22222 11111 222222 111111111 222 111    
( פתרון ) כתוב מבט שלילי מאחורי ביטוי מותנה שלוכד טקסט ownsרק אם לא מקדים לו טקסט cl, ושלוכד טקסט oudsרק כשקודם לו טקסט cl. (דוגמה קצת מומצאת, אבל מה אפשר לעשות...)
תבנית:
מחרוזת: לליצנים האלה יש כמה קלאודים . אודים.
תואם:              ^^^^ ^^^^   
( פתרון ) <h2>שלב 20: רקורסיה ומחקר נוסף</h2> RegEx: 20 צעדים קצרים לשליטה בביטויים רגולריים.  חלק 4 - 6למעשה, יש הרבה שניתן לדחוס לתוך מבוא בן 20 שלבים לכל נושא, וביטויים רגולריים אינם יוצאי דופן. ישנם יישומים וסטנדרטים רבים ושונים לביטויים רגולריים שניתן למצוא באינטרנט. אם אתה רוצה ללמוד עוד, אני מציע לך לבדוק את האתר הנפלא regularexpressions.info , זה הפניה פנטסטית ובהחלט למדתי הרבה על ביטויים רגולריים משם. אני ממליץ עליו בחום, כמו גם על regex101.com לבדיקה ופרסום היצירות שלך. בשלב האחרון הזה, אני אתן לך קצת יותר ידע על ביטויים רגולריים, כלומר איך לכתוב ביטויים רקורסיביים. רקורסיות פשוטות הן די פשוטות, אבל בואו נחשוב מה זה אומר בהקשר של ביטוי רגולרי. התחביר לרקורסיה פשוטה בביטוי רגולרי נכתב כך: (?R)?. אבל, כמובן, תחביר זה חייב להופיע בתוך הביטוי עצמו. מה שנעשה זה לקנן את הביטוי בתוך עצמו, מספר שרירותי של פעמים. לדוגמה:
תבנית: (hey(?R)?oh) 
מחרוזת:   heyoh heyyoh heyheyohoh hey heyhey hey heyheyohoh  
תואמים: ^^^^^ ^^^^^^^^^^^^^^^^^^^^ 
קבוצה:    11111 1111111111 1111111111    
( דוגמה ) מכיוון שהביטוי המקנן הוא אופציונלי ( (?R)ואחריו ?), ההתאמה הפשוטה ביותר היא פשוט להתעלם לחלוטין מהרקורסיה. אז, hey, ולאחר מכן ohתואמים ( heyoh). כדי להתאים כל ביטוי מורכב מזה, עלינו למצוא את המחרוזת המשנה התואמת שמקוננת בתוך עצמה בנקודה בביטוי שבה הכנסנו (?R)את הרצף. במילים אחרות, נוכל למצוא heyheyohoh או heyheyheyohohoh, וכן הלאה. אחד הדברים הנהדרים בביטויים המקוננים האלה הוא שבניגוד להפניות לאחור וקבוצות לכידה בשם, הם לא מגבילים אותך לטקסט המדויק שהתאמת קודם לכן, תו אחר תו. לדוגמה:
דפוס: ([Hh][Ee][Yy](?R)?oh) 
מחרוזת:   heyoh heyyoh hEyHeYohoh hey heyhey hEyHeYHEyohohoh  
תואמים: ^^^^^ ^^^^^^^^^^^^^^^ ^^^^^^^^^^ 
קבוצה:    11111 1111111111 111111111111111    
( דוגמה ) אתה יכול לדמיין שמנוע הביטויים הרגולריים ממש מעתיק ומדביק את הביטוי הרגולרי שלך לתוך עצמו מספר שרירותי של פעמים. כמובן, זה אומר שלפעמים זה לא יעשה את מה שאולי קיווית:
תבנית: ((?:\(\*)[^*)]*(?R)?(?:\*\))) 
מחרוזת: (* תגובה (* מקוננת *) לא *)
תואמים:            ^^^^^^^^^^^^ 
קבוצה:               111111111111    
( דוגמה ) האם אתה יכול לדעת מדוע הביטוי הרגולרי הזה תפס רק את ההערה המקוננת ולא את ההערה החיצונית? דבר אחד בטוח: כשאתה כותב ביטויים רגולריים מורכבים, תמיד בדוק אותם כדי לוודא שהם פועלים כפי שאתה חושב שהם יעבדו. העצרת המהירה הזו לאורך כבישי הביטויים הקבועים הגיעה לקיצה. אני מקווה שנהנית מהמסע הזה. ובכן, ולבסוף, אשאיר כאן, כפי שהבטחתי בהתחלה, מספר קישורים שימושיים ללימוד מעמיק יותר של החומר:
הערות
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION