אתה נמצא כאן יסודות השפה  >>  ביטויים רגולריים - PCRE  >>  תחביר

תחביר

הקדמה

PHP היא שפה לתכנות באינטרנט, ועיקרה הוא להוציא פלט בצורה של טקסט (לרוב HTML). לכן יש צורך לחזק את השפה בכל הקשור למחרוזות. Perl היא שפה מאוד חזקה בנושא של מחרוזות, ו-PHP שנגזרת (בין היתר) משפה זו, ירשה ממנה את יכולת העבודה החזקה עם מחרוזות. אחד הדברים החשובים שמצויים ב-PHP הם ביטויים רגולריים (PCRE = Perl Compatible Regular Expressions).

השימוש העיקרי בביטויים רגולריים הוא בחיפוש אחר התאמה של מחרוזת כלשהי לפי תבנית מוגדרת. תבניות של ביטויים רגולריים הם מחרוזות שיש להם תחביר מיוחד. כל ביטוי רגולרי צריך להופיע בין הסימנים / (למשל: התבנית /dog/ שמתאימה למחרוזות שמכילות את המילה dog). הגדרת תבניות של ביטויים רגולריים מסובכת ומורכבת, אך ידיעת נושא זה תקל במקרים רבים על המתכנתים, ותאפשר תכנות פשוט עבור דברים שיכולים להיות מאוד מסובכים ללא PCRE.

סימנים מיוחדים (meta-characters)

החוכמה בביטויים רגולריים היא ליצור תבנית מסויימת שיכולה להתאים למחרוזות מסויימות. אותיות בביטוי רגולרי מסמלות את האות עצמה (בדר"כ, אלא אם מופיעים אחרי \), אך ישנם תווים, סימנים, שיש להם משמעות מיוחדת והם לא מסמלים את התו עצמו. אלו הם סימנים מיוחדים (meta-characters), שמסמלים תווים אחרים או חוקיות מסויימת בביטוי הרגולרי. הסימנים המיוחדים מוכרים בכל התבנית, והם מקבלים משמעות מיוחדת בתוך התבנית.

הסימנים המיוחדים, meta-characters, שמוכרים בכל התבנית, הם:

הסימן המיוחד משמעות הסימן
\ "תו בריחה" כללי (escape character), שיש לו כמה מטרות (תראו בהמשך).
^ מסמל תחילת מחרוזת.
$ מסמל סוף מחרוזת.
. מסמל כל תו, פרט ל-\n (שורה חדשה).
[ פותח מחלקת תווים (הסבר בהמשך).
] סוגר מחלקת תווים.
| מסמל אלטרנטיבה, מעין ביטוי OR.
( פותח תת-תבנית, תבנית בתוך תבנית.
) סוגר תת-תבנית.
? מסמל כמות: 0 או 1 פעמים.
* מסמל כמות: 0 או יותר פעמים.
+ מסמל כמות: 1 או יותר פעמים.
{ פותח כמות של מינימום/מקסימום.
} סוגר כמות של מינימום/מקסימום.

לדוגמא: הביטוי /d.g/ מתאים למחרוזות שמכילים "dog", "dig", "dfb" או "d g", ובעצם לכל מחרוזת שמתחילה ב-d, אחריה יש תו כלשהו (שונה מ-\n), ובסוף יש g. ואילו הביטוי /do?g/, לדוגמא, מתאים למחרוזות "dg" ו-"dog" בלבד.
הסבר מפורט על הסימנים המיוחדים תראה בהמשך.

1. תו הבריחה \

לתו הבריחה (backslash \) יש מספר תפקידים חשובים. ראשית, אם אנו רוצים להשתמש בתו של סימן מיוחד ללא משמעותו המיוחדת, צריכים "להבריח" אותו עם \. למשל, אם רוצים להשתמש בתבנית כלשהי בתו * אז אנו כותבים אותו בתבנית כ-\* (לדוגמא: /\/\*/ מתאים למחרוזת /*). למעשה, תו הבריחה מבטל כל משמעות מיוחדת של סימן מיוחד, וזה בטוח להשתמש בו עבור כל סימן שאינו אות או מספר. גם אם לסימן אין משמעות מיוחדת, השימוש ב-\ אינו פוגע במשמעות הביטוי.

תפקיד נוסף של תו הבריחה הוא לציין תווים שלא ניתנים להדפסה, כמו: שורה חדשה, טאב וערך הקסאדצימלי. התווים שלא ניתנים להדפסה מובאים בטבלה הבאה:

הצירוף משמעות הצירוף
\a פעמון. צירוף המסמל צפצוף במחשב, תו ה-BEL. (hex 07)
\cx Control-x. צירוף שמסמל לחיצה על מקש Control יחד עם תו x כלשהו.
\e Escape. (hex 1B)
\f formfeed. (hex 0C)
\n שורה חדשה. (hex 0A)
\r חזרה לשורה חדשה. (hex 0D)
\t טאב. (hex 09)
\xhh מסמל ערך הקסאדצימלי. (ניתן לכתוב עד 2 מספרים הקסאדצימליים במקום hh).
\ddd מסמל ערך אוקטאלי (אם מתחיל ב-0), או ייחוס חוזר, back reference (הסבר בהמשך).

שימוש נוסף בתו הבריחה הוא לסמל קבוצת תווים מסוג מסויים. ראה את הטבלה הבאה:

הצירוף קבוצת התווים
\d כל ספרה דצימלית (0,1,2,...,9).
\D כל תו שאינו ספרה דצימלית.
\s כל תו לבן (שורה חדשה, רווח, טאב...).
\S כל תו שאינו תו לבן.
\w כל תו של מילה (מילה: אות, ספרה וקו תחתון).
\W כל תו שאינו תו של מילה.

כל צירוף מייצג תו בודד מאותה הקבוצה, למשל: /\d/ יכול להתאים ל-3 או ל-8, אך לא ל-38.

עוד שימוש של תו הבריחה הוא כדי לבדוק גבולות מסויימים:

הצירוף הגבול שבודק
\b גבול של מילה. (שווה ערך ל-\W\w).
\B לא גבול של מילה. (שווה ערך ל-\w\w).
\A תחילה אבסולוטית של מחרוזת. (לא תמיד דומה ל-^).
\Z סוף שורה או סוף של מחרוזת.
\z סוף אבסולוטי של מחרוזת. (לא תמיד דומה ל-$).

2. תחילת וסוף מחרוזת ^ $

הסימן ^ הוא תו בדיקה שקובע את תחילתו של המחרוזת. למשל, הביטוי /^dog/ מתאים למחרוזת "dogs run fast", אך לא למחרוזת "I have a dog".
הסימן $ הוא תו בדיקה שקובע את סופו של המחרוזת. למשל, הביטוי /dog$/ מתאים למחרוזת "I have a dog", אך לא למחרוזת "I have dogs".

לפעמים הסימנים ^ ו-$ בודקים תחילה וסוף של שורות בודדות, כאשר מצויין המודיפיקטור PCRE_MULTILINE (ראה הסבר בדף מודיפיקטורים). במקרה שמצויין המודיפיקטור הנ"ל, הביטוי /dog$/, למשל, יתאים למחרוזת "I have a dog\nand it is brown." וגם למחרוזת "I have a dog".

3. הסימן נקודה .

הסימן נקודה מסמל כל תו יחיד כלשהו (גם תווים שלא ניתנים להדפסה, פרט לשורה חדשה - \n).
לדוגמא: הביטוי /ab./ מתאים למחרוזות "abc", "ab^", "!ab cd!" ו-"babab", אך לא למחרוזות "ab", "ab\nc" ו-"ba ba".

4. מחלקת תווים []

מחלקת תווים מתאימה תו אחד מתוך התווים שבמחלקה, ואת המחלקה פותחים עם [ וסוגרים עם ]. למשל, המחלקה [aeiou] מתאימה לאות ניקוד קטנה אחת, והמחלקה [AEIOU] מתאימה לאות ניקוד גדולה אחת.

הסימנים המיוחדים שמוכרים בתבנית כלשהי, לא מוכרים בתוך מחלקת תווים, או שהם מקבלים שם משמעות אחרת. הסימנים המיוחדים המוכרים בתוך מחלקת תווים הם:

הסימן המיוחד משמעות הסימן
\ "תו בריחה" כללי (escape character).
^ שלילה. הופך את המחלקה ל-"כל התווים חוץ מ...". (עובד רק אם הוא התו הראשון במחלקה).
- מסמל טווח של תווים.
] סוגר את מחלקת התווים.

הסימן המיוחד ^ מסמל שלילה של מחלקת התווים, רק במידה והוא מופיע בהתחלה (אחרת אין לו שום משמעות מיוחדת במחלקה). הכוונה בשלילה של המחלקה, היא התאמה של כל תו כלשהו חוץ מהתווים שמופיעים במחלקה. למשל, המחלקה [^aeiou] מתאימה כל תו כלשהו חוץ מאותיות הניקוד הקטנות (המחלקה מתאימה גם לתו E, למשל, וגם לתו של שורה חדשה, \n). אבל המחלקה [a^eiou] לא שוללת את המחלקה, כי הסימן ^ לא מופיע בתחילת המחלקה, ולכן אין לו שום משמעות מיוחדת, ועל-כן המחלקה מתאימה לכל אות ניקוד קטנה ולתו ^. אם צריך להשתמש בתו ^ בתוך המחלקה, אז רצוי להבריח אותו, ולכתוב אותו עם תו הבריחה - \^.

הסימן המיוחד - מסמל טווח של תווים, במידה ויש תו לפניו ואחריו. למשל, המחלקה [a-j] מתאימה כל תו שנמצא בטווח בין a ל-j (כולל הקצוות). אך, למשל, בתבנית [a-] אין כלל שימוש בטווח, כי הסימן - מופיע בסוף המחלקה ואין תווים גם לפניו וגם אחריו. הטווח מחושב על-פי הערך ה-ASCII של התווים שמגדירים את קצוות הטווח, כך למשל, התבנית [\011-\037] מתאימה לכל תו שערכו ה-ASCII הוא בין 011 (מספר אוקטאלי שערכו 9) ובין 037 (מספר אוקטאלי שערכו 31).

ניתן להשתמש כאן גם בצירופים המיוחדים שמגדירים קבוצות תווים מסוג מסויים, שבהחלט יכולים לפשט את הביטוי. למשל, המחלקה [\dABCDEFabcdef] מתאימה לכל ספרה הקסאדיצמלית. ולמשל, המחלקה [^\W_] מתאימה לכל תו שהוא אות או ספרה.

5. אלטרנטיבה |

התו המיוחד | מסמל אלטרנטיבה, ומשמעותו הוא מעין יחס "או" (OR) בין ביטויים. למשל, התבנית /He|She/ מתאימה למחרוזות "He" או "She". ניתן להשתמש בכל מספר של אלטרנטיבות. בחיפוש אחר אלטרנטיבה, הולכים משמאל לימין, והאלטרנטיבה הראשונה שמתאימה, היא האלטרנטיבה הנבחרת. השימוש העיקרי בסימן המיוחד הזה הוא בתת-תבניות (הסבר בהמשך).

6. תת-תבנית ()

תת-תבנית היא בעצם יצירת תבנית פנימית בתוך התבנית החיצונית, תבנית בתוך תבנית. לתת-תבנית יש 2 שימושים עיקריים: איגוד רצף של אלטרנטיבות, ותפיסה של תתי-מחרוזות לייחוס חוזר (back reference).

דוגמא לאיגוד של אלטרנטיבות, יש בתבנית /can(dle|cel|)/ שמתאימה למחרוזות "can", "candle" ו-"cancel". ללא שימוש בסוגריים המעוגלים (תת-תבנית), התבנית הייתה מתאימה למחרוזות "candle", "cel" והמחרוזת הריקה.

השימוש היותר חשוב של תתי-תבניות הוא כדי לתפוס תתי-מחרוזות לייחוס חוזר (back reference). כאשר אנו משתמשים בתת-תבנית, ויש לנו התאמה של תת-התבנית במחרוזת כלשהי, אז ההתאמה שנמצאה במחרוזת נתפסת ונשמרת כתת-מחרוזת שניתן להשתמש בה בייחוס חוזר. למשל, התבנית /small (dog|cat)/ מתאימה למחרוזת "small dog", ויש לנו התאמה של תת-התבנית (dog|cat) עם תת-המחרוזת "dog", ולכן תת-המחרוזת "dog" נתפסת ונשמרת. ניתן להשתמש בהרבה תת-תבניות בביטוי כלשהו, ולכן תת-המחרוזות שנתפסות נשמרות בתוך מערך פנימי ממוספר. המספור של תת-המחרוזות מתחיל מ-1, וסופרים משמאל לימין לפי סימן הפתיחה ( של תת-התבנית. למשל, התבנית /the ((red|white) (queen|king))/ מתאים למחרוזת "the white queen", ותת-המחרוזות שנתפסות בה הן "white queen", "white" ו-"queen", והן ממוספרות 1, 2 ו-3 בהתאמה.

פעמים רבות משתמשים בתת-תבנית כדי לפשט את הביטוי, אך לא תמיד אנו רוצים לשמור את תת-המחרוזת שנתפסת. כדי למנוע את שמירת תת-המחרוזת שנתפסת בתת-התבנית, כותבים ?: אחרי סימן הפתיחה של תת-התבנית. כאשר לא שומרים את התבנית שנתפסת, אז גם לא סופרים אותה. למשל הביטוי /the ((?:red|white) (queen|king))/ מתאים שוב למחרוזת "the white queen", אך הפעם רק תת-המחרוזות "white queen" ו-"queen" נתפסות, וממוספרות 1 ו-2 בהתאמה.

7. כמתים {} * + ?

כמתים יכולים להופיע אחרי תו בודד (יכול להיות גם צירוף מיוחד), מחלקת תווים, ייחוס חוזר ותת-תבנית, והם מציינים כמה פעמים מותר לחזור על ביטוי מסויים. הכמת הכללי מציין את מספר הפעמים המינימלי והמקסימלי שמותר לביטוי מסויים לחזור על עצמו, והתחביר שלו הוא: {n,m} כך ש-n הוא הכמות המינימלית ו-m הוא הכמות המקסימלית (צריך להיות גדול או שווה ל-n). למשל, הביטוי /z{2,4}/ מתאים למחרוזות "zz", "zzz" ו-"zzzz".

הכמת הכללי יכול להופיע גם בצורה של {n,} שמציין את מספר החזרות המינימלי בלבד, ואין גבול עליון. למשל, הביטוי /z{2,}/ מתאים לכל המחרוזות שיש בהן 2 z-ים או יותר (ברציפות).
הכמת הכללי יכול להופיע גם בצורה של {n} שמציין את מספר החזרות המדוייק (לא יותר ולא פחות). למשל, הביטוי /z{2}/ מתאים רק למחרוזת "zz" שיש בה בדיוק 2 z-ים (ברציפות).

הסימנים המיוחדים * + ? הם כמתים מיוחדים:

הכמת שקול ל- משמעות
* {0,} מופיע 0 או יותר פעמים.
+ {1,} מופיע לפחות פעם אחת.
? {0,1} לא מופיע כלל, או מופיע פעם אחת בלבד.

לדוגמא, התבנית /a+b?/ מייצגת מחרוזות שמתחילות ב-a, ולאחר רצף ה-a-ים יש b אחת לכל היותר. מחרוזות שמתאימות לתבנית זו, למשל: "aaaaab", "aaa", "ab", "a". ומחרוזות שלא מתאימות לתבנית, למשל: "b", "bbb", "cccb".

8. ייחוס חוזר - back reference

כבר ראינו שאם יש התאמה של תת-תבנית, אז תת-המחרוזת המתאימה לה נתפסת ונשמרת, ובנוסף מקבלת מספר לפי מיקום התת-תבנית (ראה את החלק של תת-תבנית בדף זה). ייחוס חוזר (back reference) משמש להתייחסות לתת-מחרוזת שנתפסה בתת-תבנית כלשהי, על-ידי ציון המספר של תת-התבנית, בצורה של \m כך ש-m מציין את מספר תת-התבנית. למשל, בביטוי /the ((red|white) (queen|king))/, יש לנו 3 תתי-תבניות שנתפסים. המחרוזת "the white queen" מתאימה לביטוי הנ"ל, ויש לו 3 ייחוסים חוזרים: \1 שמתייחס לתת-המחרוזת הראשונה ("white queen"), \2 שמתייחס לתת-המחרוזת השנייה ("white"), ו-\3 שמתייחס לתת-המחרוזת השלישית ("queen").

כאשר משתמשים בייחוס חוזר בתוך ביטוי רגולרי, אז מחליפים את הייחוס החוזר בתת-המחרוזת שנתפסה באותו המספר של הייחוס החוזר. לדוגמא, הביטוי /(sens|respons)e and \1ibility/, מתאים למחרוזות "sense and sensibility" ו-"response and responsibility", אך לא למחרוזת "sense and responsibility" (כי תת-המחרוזת שנתפסה היא "sens" ולא "respons"), וגם לא למחרוזת "Sense and sensibility" (כי המחרוזת שנתפסה היא "Sens" ולא "sens").

כאשר משתמשים בייחוס חוזר, אז ניתן לרשום בייחוס החוזר רק מספרים שיש להם תת-תבניות משמאל לייחוס החוזר. לדוגמא, הייחוס החוזר \2 בביטוי /(ab|cd)\2(cd|ef)/ ייכשל, כי הייחוס החוזר \2 מתייחס לתת-מחרוזת שעדיין לא ידועה באותו שלב, מפני שתת-התבנית 2 נמצאית מימין לייחוס החוזר.


תגובות בנושא

עוד תו מיוחד 06-12-02 09:01
 חגי
#242

אין את התו- i כמו בפרל שמבטל את הcaps -sensitive בביטוי?

תגובה: עוד תו מיוחד 06-12-02 09:01
 אלי חן (מנהל)
#245

זה לא בדיוק תו מיוחד אלא מודיפיקטור שבאמת מבטל את ה case-sensitive. הסבר על כך בדף הבא.

אחלה מאמר:: 10-12-02 05:00
 יקיר סיטבון
#463

חן, אתה גדול.

רק ממך הצלחתי להבין את הנושא של regex ביסודיות.

ישר כח, יקיר.

זה כמו ב-javascript? 31-10-02 23:01
 יאיר
#524

אני רוצה לדעת האם רגלר אקספרשין כאן, זה אותו
דבר כמו ב-javascript?

תשובה: זה כמו ב-javascript? 31-10-02 23:02
 אלי חן (מנהל)
#530

כעיקרון, כן!
הסינטקס של הביטויים הרגולריים אמור להיות זהה בכל שפה. ואם לא, אז יש שינויים קטנים פה ושם, אבל הרעיון המרכזי והסינטקס הראשי זהים.
מה שכן, כל שפה מגדירה בדרך שלה את הפונקציות הנוגעות בביטויים רגולריים, אז כאן ככל הנראה יש שינויים.
בכל מקרה, הביטויים הרגולריים ב-PHP מבוססים על Perl, לכן קוראים לזה גם PCRE, שזה Perl-Compatible Regular Expressions

שימוש בהחלפה עם ביטויים רגולריים 07-12-03 04:01
 Bartzy
#941

איך עושים החלפה של מילה מסויימת במילה אחרת במחרוזת (ישנה אפשרות שיופיעו כמה מילים באותה מחרוזות) רק בשני תנאים:

1. שהמילה נפרדת
2. שהמילה לא מופיעה בתוך לינק

תודה רבה :)

תומך בעברית? 08-12-03 09:00
 אורי
#1054

כשאני עושה הרשמה ואני רוצה רק אותיות בעברית מה
אני עושה? אם אני ישתמש ב [[:alpha:]] זה יעבוד
על עברית? מה עדיף לעשות?

רק אותיות עבריות 09-12-03 18:02
 אלי חן (מנהל)
#1121

השימוש ב [[:alpha:]] הוא בפונקציות ereg_* ולא preg_*. חוץ מזה, alpha תכלול גם תתאים לאותיות באנגלית.
כדי לבדוק רק אותיות עבריות השתמש במחלקת תווים, כך:
[א-ת]

איך מייצגים... 01-12-04 19:00
 איתי
#1403

איך אפשר לייצג מחרוזת ריקה בביטוים רגולריים.
לדוגמה אני רוצה ביטוי שיתאים גם לכתובת אימייל וגם למחרוזת ריקה אך לא לשום אופציה אחרת...


לדף הקודםביטויים רגולריים - PCRE -הקודם
לתחילת הדףלתחילת הדף
הבא- מודיפיקטוריםלדף הבא