ביטויים רגולריים, או regex, הם אחד הכלים הכי קטנים והכי יעילים בארגז הכלים של מפתחים: חיפוש טקסט, אימות קלט, ניקוי קבצים, חילוץ נתונים מלוגים, בדיקות ב־Python, סקריפטים בלינוקס, וגם עבודה בסיסית ב־JavaScript. הבעיה היא שלא תמיד זוכרים את התחביר המדויק, במיוחד כשצריך משהו עכשיו: כתובת מייל, מספר, תאריך, שורה ריקה, או טקסט בין סוגריים.
המדריך הזה הוא דף עזר מעשי לביטויים רגולריים בעברית: 30 תבניות נפוצות, הסבר קצר לכל אחת, דוגמאות להרצה, טעויות אמיתיות שתראו במסך, ומה עושים כש־regex “כמעט עובד” אבל תופס יותר מדי או פחות מדי. אם אתם עדיין בונים בסיס בתכנות, כדאי לשמור גם את מדריך צעדים ראשונים לידכם; ואם רוב העבודה שלכם היא בפייתון, יש כאן המשך טבעי למדריך פייתון.
מה צריך להכין מראש
אפשר לעבוד עם ביטויים רגולריים כמעט בכל שפה. במאמר הזה נשתמש בשלושה כלים נפוצים ובטוחים להרצה:
- Python 3 עם הספרייה הסטנדרטית
re. - Linux/macOS bash עם
grep, בלי לשנות קבצים. - Node.js להרצת דוגמאות JavaScript בסיסיות.
לפני שמתחילים, חשוב לזכור: regex אינו פרסר מלא לכל פורמט. למשל, אפשר לבדוק מייל בצורה סבירה, אבל אימות מושלם של כל כתובת תקנית הוא נושא מורכב. אותו דבר לגבי HTML, SQL או JSON: לבדיקות פשוטות זה עוזר; לפענוח מלא משתמשים בכלים ייעודיים.
תחביר בסיסי שחייבים להכיר
| סימן | משמעות | דוגמה |
|---|---|---|
. |
כל תו יחיד, לרוב חוץ מירידת שורה | a.c יתפוס abc |
* |
אפס או יותר חזרות | ab* |
+ |
אחת או יותר חזרות | \d+ |
? |
אפס או אחת, או הפיכת כימות ל”עצל” | colou?r |
^ |
תחילת מחרוזת או שורה | ^ERROR |
$ |
סוף מחרוזת או שורה | \.txt$ |
[] |
קבוצת תווים | [abc] |
() |
קבוצה ללכידה | (\d{4}) |
| |
או | cat|dog |
\b |
גבול מילה | \bcat\b |
30 תבניות Regex שימושיות
התבניות כאן נועדו לשימוש מעשי. במקרים רגישים, כמו אימות נתוני משתמשים לפני שמירה למסד נתונים, בדקו גם בצד השרת ואל תסמכו רק על בדיקה בדפדפן.
| # | מה רוצים למצוא | תבנית | הסבר קצר |
|---|---|---|---|
| 1 | מספר שלם חיובי | ^\d+$ |
רק ספרות, מתחילת המחרוזת עד סופה. |
| 2 | מספר שלם עם מינוס אפשרי | ^-?\d+$ |
תו מינוס אחד יכול להופיע בהתחלה. |
| 3 | מספר עשרוני | ^-?\d+(\.\d+)?$ |
חלק עשרוני אופציונלי אחרי נקודה. |
| 4 | מילה באנגלית | ^[A-Za-z]+$ |
אותיות בלבד, בלי רווחים או ספרות. |
| 5 | שם משתמש פשוט | ^[A-Za-z0-9_]{3,20}$ |
אותיות, ספרות וקו תחתון, אורך 3 עד 20. |
| 6 | מייל בסיסי | ^[^\s@]+@[^\s@]+\.[^\s@]+$ |
בדיקה סבירה, לא אימות תקן מלא. |
| 7 | תאריך בפורמט שנה-חודש-יום | ^\d{4}-\d{2}-\d{2}$ |
בודק צורה כמו 2026-10-26, לא תקינות קלנדרית. |
| 8 | שעה 24 שעות | ^([01]\d|2[0-3]):[0-5]\d$ |
שעות 00-23 ודקות 00-59. |
| 9 | קובץ טקסט | \.txt$ |
סיומת .txt בסוף המחרוזת. |
| 10 | שורה ריקה | ^\s*$ |
אפס או יותר תווי רווח בלבד. |
| 11 | רווחים כפולים | \s{2,} |
שני תווי רווח או יותר ברצף. |
| 12 | מילה שלמה | \berror\b |
יתפוס error אך לא terror. |
| 13 | כתובת IPv4 בסיסית | ^(\d{1,3}\.){3}\d{1,3}$ |
בודק מבנה, לא מגביל כל חלק ל־255. |
| 14 | Hex color | ^#?[0-9A-Fa-f]{6}$ |
צבע כמו #ffcc00 או בלי סולמית. |
| 15 | טקסט בין סוגריים | \(([^()]*)\) |
לוכד תוכן פשוט בלי סוגריים מקוננים. |
| 16 | טקסט בין מרכאות כפולות | "([^"]*)" |
לוכד עד המרכאות הבאות. |
| 17 | תגית HTML פשוטה | <[^>]+> |
שימושי לחיפוש בסיסי, לא לפענוח HTML. |
| 18 | URL בסיסי | ^https?://[^\s]+$ |
מתחיל ב־http:// או https://. |
| 19 | מפתח בסגנון UPPER_SNAKE | ^[A-Z][A-Z0-9_]*$ |
מתאים לשמות קבועים כמו MAX_SIZE. |
| 20 | מילה בעברית | ^[א-ת]+$ |
אותיות עבריות בלבד, בלי ניקוד. |
| 21 | אותיות עברית ורווחים | ^[א-ת\s]+$ |
שמות או משפטים קצרים בעברית. |
| 22 | UUID פשוט | ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$ |
מבנה UUID נפוץ. |
| 23 | שורות שמתחילות בהערה | ^\s*# |
רווחים ואז סולמית. |
| 24 | CSV פשוט, ערכים בלי מרכאות | ^[^,\n]+(,[^,\n]+)*$ |
שורה עם ערכים מופרדים בפסיקים. |
| 25 | חילוץ מספר מתוך טקסט | \d+ |
כל רצף ספרות ראשון או כל הרצפים. |
| 26 | הסרת רווחים בתחילת שורה | ^\s+ |
משמש עם החלפה למחרוזת ריקה. |
| 27 | הסרת רווחים בסוף שורה | \s+$ |
נפוץ בניקוי קבצי קוד וטקסט. |
| 28 | חיפוש TODO | \bTODO\b |
מוצא סימוני משימה בקוד. |
| 29 | גרסה סמנטית בסיסית | ^\d+\.\d+\.\d+$ |
כמו 1.4.2. |
| 30 | הכול עד הפסיק הראשון | ^[^,]* |
שימושי לפיצול מהיר של שורה. |
דוגמה 1: בדיקת קלט בפייתון
הדוגמה הבאה מריצה כמה תבניות על רשימת ערכים. היא לא משנה קבצים ולא משתמשת בספריות חיצוניות.
import re
patterns = {
"username": r"^[A-Za-z0-9_]{3,20}$",
"email": r"^[^\s@]+@[^\s@]+\.[^\s@]+$",
"date": r"^\d{4}-\d{2}-\d{2}$",
}
samples = {
"username": ["dev_123", "ab", "bad-name"],
"email": ["[email protected]", "missing-at.example", "a@b"],
"date": ["2026-10-26", "26-10-2026", "2026-1-2"],
}
for name, pattern in patterns.items():
print(name)
for value in samples[name]:
result = "OK" if re.fullmatch(pattern, value) else "NO"
print(f" {value}: {result}")הקוד משתמש ב־re.fullmatch, כלומר כל המחרוזת חייבת להתאים לתבנית. פלט צפוי בקירוב:
username
dev_123: OK
ab: NO
bad-name: NO
email
[email protected]: OK
missing-at.example: NO
a@b: NO
date
2026-10-26: OK
26-10-2026: NO
2026-1-2: NOשימו לב ל־a@b: לפי התבנית כאן הוא לא תקין כי חסרה נקודה אחרי החלק של הדומיין. בפרויקטים אמיתיים כדאי לבצע אימות נוסף לפי הצורך, ולא לנסות לדחוס את כל כללי העולם לתבנית אחת מפלצתית.
דוגמה 2: חילוץ נתונים מלוגים בפייתון
זה שימוש קלאסי: יש שורות לוג, ורוצים להוציא תאריך, רמה והודעה. במקום לחתוך לפי אינדקסים שבירים, משתמשים בקבוצות.
import re
log_text = """2026-10-26 INFO service started
2026-10-26 ERROR missing config
bad line
2026-10-27 WARN slow response"""
pattern = re.compile(r"^(\d{4}-\d{2}-\d{2})\s+(INFO|WARN|ERROR)\s+(.+)$")
for line in log_text.splitlines():
match = pattern.fullmatch(line)
if match:
date, level, message = match.groups()
print(f"{date} | {level} | {message}")התבנית מחלקת כל שורה לשלושה חלקים: תאריך, רמת לוג, והודעה. השורה bad line לא מודפסת כי היא לא מתאימה למבנה. הפלט הצפוי:
2026-10-26 | INFO | service started
2026-10-26 | ERROR | missing config
2026-10-27 | WARN | slow responseדוגמה 3: חיפוש בלינוקס או macOS עם grep
הדוגמה הבאה מיועדת ל־Linux/macOS עם bash. היא יוצרת קובץ זמני בתיקייה הנוכחית, מחפשת שורות שמכילות TODO, ואז מוחקת את הקובץ.
cat > regex-demo.txt <<'EOF'
TODO write tests
done update docs
TODO review config
note without marker
EOF
grep -E '\bTODO\b' regex-demo.txt
rm regex-demo.txtהפקודה grep -E מפעילה תחביר מורחב. הביטוי \bTODO\b מחפש את המילה השלמה TODO. הפלט הצפוי:
TODO write tests
TODO review configאם אתם עובדים על Windows PowerShell, התחביר של יצירת הקובץ שונה, אבל רעיון ה־regex עצמו נשאר דומה בכלים רבים.
דוגמה 4: החלפה ב־JavaScript
ב־JavaScript משתמשים ב־RegExp או בליטרל בין לוכסנים. כאן ננקה רווחים כפולים ונחלץ מספרים.
const text = "Order 17 costs 250 units";
const cleaned = text.replace(/\s{2,}/g, " ");
const numbers = cleaned.match(/\d+/g) || [];
console.log(cleaned);
console.log(numbers.join(","));אפשר להריץ את הקובץ עם node filename.js. הדגל g אומר “מצא את כל ההתאמות”, לא רק את הראשונה. הפלט הצפוי:
Order 17 costs 250 units
17,250איך לבחור בין search, match ו-fullmatch
בפייתון יש הבדל חשוב בין שלוש פעולות נפוצות:
re.searchמחפש התאמה בכל מקום במחרוזת.re.matchמחפש התאמה רק בתחילת המחרוזת.re.fullmatchדורש שכל המחרוזת תתאים.
אם אתם בודקים קלט, בדרך כלל תרצו fullmatch. אם אתם מחפשים בתוך טקסט ארוך, search או findall יתאימו יותר. זו אחת הסיבות לכך שתבנית יכולה להיראות נכונה ועדיין להחזיר תוצאה מפתיעה.
תקלות נפוצות והודעות שגיאה אמיתיות
re.error: unterminated character set at position 0
זה קורה כשפותחים קבוצת תווים עם [ ולא סוגרים אותה. לדוגמה, [abc. התיקון: לסגור עם ], כלומר [abc]. אם רציתם לחפש סוגר מרובע ממש, כתבו \[.
re.error: bad escape \p at position 0
ב־Python re אין תמיכה מובנית ב־\p{...} כמו בחלק ממנועי regex אחרים. במקום \p{L}, השתמשו בטווחים שמתאימים לצורך, למשל [A-Za-z] לאנגלית או [א-ת] לעברית בסיסית. אם אתם צריכים תמיכת Unicode מתקדמת, בדקו היטב את הכלים הזמינים בפרויקט, אבל אל תניחו שכל מנוע regex מתנהג אותו דבר.
re.error: look-behind requires fixed-width pattern
בפייתון, מבט לאחור כמו (?<=...) חייב להיות באורך קבוע. תבנית כמו (?<=\d+) תיכשל כי \d+ יכול להיות באורכים שונים. פתרון נפוץ: ללכוד את החלק הרצוי בקבוצה במקום להשתמש ב־lookbehind משתנה.
SyntaxError: Invalid regular expression: /[/: Unterminated character class
זו שגיאת JavaScript שמקבילה לרעיון של סוגר מרובע שלא נסגר. למשל /[ אינו ביטוי תקין. תקנו ל־/[abc]/ או, אם מחפשים את התו עצמו, /\[/.
טעויות לוגיות שלא תמיד זורקות שגיאה
לא כל בעיית regex מסתיימת בהודעת שגיאה. הרבה פעמים הביטוי תקין, אבל עושה דבר לא נכון:
- שימוש ב־
.*בצורה חמדנית: בתבנית"<.*>"עלולים לתפוס יותר מדי. נסו<.*?>או תבנית מגבילה כמו<[^>]+>. - שכחת עוגנים:
\d+ימצא ספרות בתוך טקסט. אם רוצים רק מספר שלם כמחרוזת מלאה, כתבו^\d+$. - בלבול בין נקודה רגילה לנקודה מיוחדת:
.מתאים כמעט לכל תו. כדי לחפש נקודה ממש, כתבו\.. - בריחה כפולה במחרוזות: בפייתון נוח להשתמש ב־raw string כמו
r"\d+". אחרת תצטרכו לחשוב על בריחות של השפה וגם של regex.
איך לבדוק תבנית שלב אחר שלב
- התחילו מקטן: קודם מצאו ספרה עם
\d, אחר כך רצף עם\d+, ורק אז הוסיפו עוגנים. - הכינו דוגמאות חיוביות ושליליות: למשל מייל תקין, מייל בלי
@, ומייל עם רווח. - העדיפו קריאות: לפעמים שתי בדיקות פשוטות עדיפות על regex אחד ארוך מאוד.
- השתמשו בקבוצות רק כשצריך: אם אין צורך ללכוד ערך, אפשר להשתמש בקבוצה לא לוכדת כמו
(?:...). - בדקו באותו מנוע שבו תריצו: regex שעובד בכלי אחד לא בהכרח יעבוד זהה ב־Python, JavaScript או
grep.
שאלות קצרות שקוראים באמת שואלים
האם regex מתאים לבדיקת סיסמאות?
אפשר לבדוק אורך ותווים נדרשים, אבל אל תציגו סיסמאות אמיתיות בדוגמאות ואל תשמרו אותן כטקסט גלוי. בדיקות סיסמה הן רק שכבה אחת; אחסון מאובטח, הגבלת ניסיונות ומדיניות שרת חשובים לא פחות.
האם כדאי להשתמש ב־regex כדי לפרסר SQL?
לא. אפשר לזהות דפוסים פשוטים בטקסט, אבל לא לנתח SQL אמיתי בצורה אמינה עם regex פשוט. בהקשר של מסדי נתונים, חשוב יותר להשתמש בפרמטרים מוכנים ולהימנע מבניית שאילתות מחיבור מחרוזות. זה נכון במיוחד כשקלט מגיע ממשתמשים.
מה ההבדל בין \d לבין [0-9]?
ברוב הדוגמאות הפשוטות הן יתנהגו דומה, אבל במנועים מסוימים \d עשוי להתייחס גם לספרות Unicode. אם אתם רוצים רק ספרות ASCII, [0-9] מפורש יותר.
סיכום שימושי
ביטויים רגולריים הם לא קסם ולא תחליף לחשיבה, אבל הם כלי חד מאוד כשמשתמשים בהם נכון. שמרו את 30 התבניות, בדקו אותן על דוגמאות אמיתיות, והעדיפו פתרונות קטנים וברורים על פני ביטויים ארוכים שקשה לתחזק. אם אתם ממשיכים לתרגל בפייתון, חזרו גם למדריך פייתון ובנו לעצמכם קובץ בדיקות קטן עם re.fullmatch, re.search ו־re.sub. אחרי כמה שימושים, regex מפסיק להיראות כמו רעש ומתחיל להרגיש כמו קיצור דרך שימושי מאוד.


