דף עזר Regex: המדריך המלא לביטויים רגולריים

שלטו בביטויים רגולריים עם המדריך המקיף הזה. למדו דפוסים, תחביר, יישומים ספציפיים לשפה (Python, JavaScript, PHP, C#, Java, Go, Ruby), טרנספורמציות חיפוש/החלפה ב-VS Code ומעל 200 דוגמאות מעשיות. המקור המוחלט ל-regex למתחילים ומומחים.

G
GUi Softworks
60 דקות קריאה

מה זה Regex?

ביטויים רגולריים (regex או regexp) הם רצפי תווים המגדירים דפוסי חיפוש. הם אחד הכלים החזקים ביותר לעיבוד טקסט, זיהוי דפוסים וחילוץ נתונים.

למה להשתמש בביטויים רגולריים?

Regex חיוניים עבור:

  • אימות טפסים (אימייל, מספרי טלפון, סיסמאות)
  • חילוץ נתונים (ניתוח לוגים, גירוד דפי אינטרנט)
  • עיבוד טקסט (חיפוש והחלפה, עיצוב)
  • Refactoring קוד (שינוי שמות משתנים, עדכון תחביר)
  • חיטוי קלט (אבטחה, מניעת התקפות injection)

איך לקרוא את דף העזר הזה

המדריך מאורגן בסעיפים מתקדמים:

  1. יסודות - תחביר ודפוסים בסיסיים
  2. תכונות מתקדמות - Lookaround, קבוצות עם שם, Unicode
  3. ספציפי לשפה - דוגמאות ב-Python, JavaScript, PHP, C#, Java, Go, Ruby
  4. Regex ב-VS Code - טרנספורמציות חיפוש/החלפה עם מעל 20 דוגמאות
  5. דפוסים נפוצים - דפוסי העתק-הדבק לאימייל, URL, תאריכים ועוד
  6. מקרי שימוש מעשיים - יישומים מהעולם האמיתי
  7. פתרון בעיות - טעויות נפוצות וטיפים לביצועים

כל סעיף כולל:

  • הסברים ברורים
  • דוגמאות ויזואליות
  • קטעי קוד שאפשר להעתיק
  • טיפים מקצועיים ומלכודות

תווים ליטרליים

הregex הפשוט ביותר הוא רצף של תווים ליטרליים:

abc

מתאים ל: "abc" ב"הרצף abc"

רגישות לאותיות גדולות/קטנות

כברירת מחדל, regex רגיש לאותיות גדולות/קטנות:

  • שלום מתאים ל"שלום" אבל לא ל"שלום" (אם הוא באות שונה)
  • השתמש בדגל i להתאמה ללא רגישות: /שלום/i

תווים מיוחדים (מטא-תווים)

12 תווים אלה בעלי משמעות מיוחדת ב-regex וחייבים להיות מוחלפים עם \ כדי להתאים ליטרלית:

. ^ $ * + ? { } [ ] \ | ( )

דוגמאות:

  • \. מתאים לנקודה ליטרלית
  • \$ מתאים לסימן דולר
  • \( מתאים לסוגר ליטרלי
תו Escape דוגמה מתאים ל
. (נקודה) \. 3\.14 "3.14"
$ (דולר) \$ \$100 "$100"
* (כוכבית) \* a\*b "a*b"

מחלקות תווים

מחלקות תווים מוגדרות מראש

דפוס תיאור שווה ערך דוגמה מתאים ל
\d כל ספרה [0-9] \d\d "42"
\D כל לא-ספרה [^0-9] \D+ "abc"
\w תו מילה [a-zA-Z0-9_] \w+ "שלום_123"
\W תו לא-מילה [^a-zA-Z0-9_] \W "@", "#"
\s רווח לבן [ \t\n\r\f\v] \s+ " " (רווחים)
\S לא-רווח [^ \t\n\r\f\v] \S+ "שלום"
. כל תו חוץ משורה חדשה - a.c "abc", "a1c"

טיפ מקצועי: \w לא כולל אותיות Unicode כברירת מחדל. השתמש ב-\p{L} לתמיכה ב-Unicode (JavaScript/Python).

מחלקות תווים מותאמות אישית

דפוס תיאור דוגמה מתאים ל
[abc] מתאים לכל אחד מ-a, b, או c [aeiou] תנועות: "a", "e", "i", "o", "u"
[^abc] מתאים לכל דבר חוץ מ a, b, או c [^0-9] לא-ספרות
[a-z] טווח: אותיות קטנות [a-z]+ "hello"
[A-Z] טווח: אותיות גדולות [A-Z]+ "HELLO"
[0-9] טווח: ספרות [0-9]{4} "2025"
[a-zA-Z] משולב: כל האותיות [a-zA-Z0-9] אלפאנומרי

דוגמאות:

[aeiou]       → מתאים לכל תנועה
[^aeiou]      → מתאים לכל עיצור (לא תנועה)
[a-z0-9]      → מתאים לאותיות קטנות וספרות
[a-zA-Z0-9_]  → שווה ל-\w (תווי מילה)

כמתים

כמתים מציינים כמה פעמים דפוס צריך להתאים.

כמתים בסיסיים

דפוס תיאור דוגמה מתאים ל
* 0 או יותר ab*c "ac", "abc", "abbc", "abbbc"
+ 1 או יותר ab+c "abc", "abbc" (לא "ac")
? 0 או 1 (אופציונלי) colou?r "color", "colour"
{n} בדיוק n פעמים \d{4} "2025" (בדיוק 4 ספרות)
{n,} n או יותר פעמים \d{2,} "42", "123", "9999"
{n,m} בין n ל-m פעמים \d{2,4} "42", "123", "2025"

כמתים חמדניים לעומת עצלניים

חמדני (ברירת מחדל): מתאים למקסימום האפשרי

<.*>      → מתאים: "<div>שלום</div>" (כל המחרוזת)

עצלני (לא-חמדני): מתאים למינימום האפשרי (הוסף ? אחרי הכמת)

<.*?>     → מתאים: "<div>" ו-"</div>" בנפרד
חמדני עצלני תיאור
* *? 0 או יותר (עצלני)
+ +? 1 או יותר (עצלני)
? ?? 0 או 1 (עצלני)
{n,m} {n,m}? בין n ל-m (עצלני)

דוגמה:

טקסט: "שלום" ו-"עולם"

  • ".*" מתאים: "שלום" ו-"עולם" (חמדני)
  • ".*?" מתאים: "שלום" ו-"עולם" בנפרד (עצלני)

עוגנים וגבולות

עוגנים מתאימים למיקומים, לא לתווים.

דפוס תיאור דוגמה מתאים ל
^ תחילת מחרוזת/שורה ^שלום "שלום עולם" (בהתחלה)
$ סוף מחרוזת/שורה עולם$ "שלום עולם" (בסוף)
\b גבול מילה \bחתול\b "חתול" ב"החתול ישב" (לא "חתולה")
\B לא-גבול מילה \Bחת "חתולה" (חת לא בגבול)
\A תחילת מחרוזת (לא שורה) \Aשלום מתאים רק אם "שלום" ממש בהתחלה
\z סוף מחרוזת (לא שורה) עולם\z מתאים רק אם "עולם" ממש בסוף
\Z סוף מחרוזת (לפני שורה חדשה אחרונה) עולם\Z מתאים ל"עולם" או "עולם\n"

דוגמאות:

^חתול$       → מתאים: "חתול" (כל השורה היא "חתול")
\bחתול\b     → מתאים: "חתול" ב"החתול ישב" (מילה שלמה)
\Bחת        → מתאים: "חת" ב"חתולה" (לא בגבול)

מצב מרובה שורות (דגל m):

  • בלי m: ^ ו-$ מתאימים לתחילת/סוף כל המחרוזת
  • עם m: ^ ו-$ מתאימים לתחילת/סוף כל שורה

קבוצות וחלופה

קבוצות לכידה

קבוצות לכידה (...) זוכרות את הטקסט המתאים:

(\d+)-(\d+)   → מתאים: "123-456"
                קבוצה 1: "123"
                קבוצה 2: "456"

הפניות אחורה (שימוש חוזר בקבוצות שנלכדו):

(\w)\1        → מתאים: "aa", "bb", "cc" (תו חוזר)
(\w+) \1      → מתאים: "שלום שלום" (מילה חוזרת)

קבוצות ללא-לכידה

השתמש ב-(?:...) כשצריך לקבץ אבל לא צריך ללכוד:

(?:https?://)  → מקבץ "http://" או "https://" בלי ללכוד

למה להשתמש בללא-לכידה?

  • ביצועים טובים יותר (ללא תקורת זיכרון)
  • הפניות אחורה נקיות יותר (קבוצות ממוספרות סופרות רק קבוצות לכידה)

חלופה (OR)

השתמש ב-| ל"מתאים לזה או לזה":

חתול|כלב    → מתאים: "חתול" או "כלב"
אפ(ור|ר)    → מתאים: "אפור" או "אפר"

דוגמאות:

(מר|גב|ד"ר)\.?  → מתאים: "מר.", "גב.", "ד"ר."
https?://              → מתאים: "http://" או "https://"

קביעות Lookaround

Lookaround הן קביעות באורך אפס שמתאימות למיקום (כמו עוגנים) אבל עם תנאים.

Lookahead חיובי (?=...)

מתאים אם הדפוס קדימה מתאים (אבל לא צורך אותו):

\d(?=px)      → מתאים: "10" ב"10px" (לא את החלק "px")

מקרה שימוש: אימות סיסמה

^(?=.*[A-Z])(?=.*[a-z])(?=.*\d)(?=.*[@$!%*?&]).{8,}$

פירוק:

  • (?=.*[A-Z]) - חייב להכיל אות גדולה
  • (?=.*[a-z]) - חייב להכיל אות קטנה
  • (?=.*\d) - חייב להכיל ספרה
  • (?=.*[@$!%*?&]) - חייב להכיל תו מיוחד
  • .{8,} - לפחות 8 תווים

Lookahead שלילי (?!...)

מתאים אם הדפוס קדימה לא מתאים:

\d(?!px)      → מתאים: "10" ב"10em" (לא "10px")

מקרה שימוש: אי הכללת מילים מסוימות

\b(?!test)\w+  → מתאים למילים שלא מתחילות ב"test"

Lookbehind חיובי (?<=...)

מתאים אם הדפוס מאחור מתאים:

(?<=₪)\d+     → מתאים: "100" ב"₪100" (לא את החלק "₪")

מקרה שימוש: חילוץ מחירים

(?<=מחיר: ₪)\d+\.\d{2}  → מתאים: "29.99" ב"מחיר: ₪29.99"

Lookbehind שלילי (?<!...)

מתאים אם הדפוס מאחור לא מתאים:

(?<!₪)\d+     → מתאים: "100" אבל לא ב"₪100"

טבלת סיכום:

סוג תחביר תיאור דוגמה
Lookahead חיובי (?=...) מתאים אם אחריו... q(?=u) מתאים "q" ב"queen"
Lookahead שלילי (?!...) מתאים אם לא אחריו... q(?!u) מתאים "q" ב"iraq"
Lookbehind חיובי (?<=...) מתאים אם לפניו... (?<=₪)\d+ מתאים "10" ב"₪10"
Lookbehind שלילי (?<!...) מתאים אם לא לפניו... (?<!₪)\d+ מתאים "10" ב"10"

קבוצות לכידה עם שם

קבוצות עם שם (?<שם>...) הופכות את ה-regex לקריא יותר:

JavaScript:

const dateRegex = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
const match = '2025-01-17'.match(dateRegex);

console.log(match.groups.year);   // "2025"
console.log(match.groups.month);  // "01"
console.log(match.groups.day);    // "17"

Python:

import re

pattern = r'(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})'
match = re.search(pattern, '2025-01-17')

print(match.group('year'))   # "2025"
print(match.group('month'))  # "01"
print(match.group('day'))    # "17"

C#:

var pattern = @"(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})";
var match = Regex.Match("2025-01-17", pattern);

Console.WriteLine(match.Groups["year"].Value);   // "2025"

קבוצות אטומיות וכמתים possessive

קבוצות אטומיות (?>...)

ברגע שמתאימה, הקבוצה לא עושה backtrack. מונעת backtracking קטסטרופלי:

(?>\d+)bar    → מתאים: "123bar" (מהיר)

בלי קבוצה אטומית:

\d+bar        → מנסה: "123bar", "12bar", "1bar" (איטי באי-התאמה)

כמתים Possessive

חמדני Possessive תיאור
* *+ 0 או יותר (ללא backtracking)
+ ++ 1 או יותר (ללא backtracking)
? ?+ 0 או 1 (ללא backtracking)

מקרה שימוש: מניעת backtracking קטסטרופלי בדפוסים מורכבים.


תמיכת Unicode

מנועי regex מודרניים תומכים בקטגוריות וסקריפטים של Unicode.

קטגוריות Unicode \p{...}

JavaScript (ES2018+):

const letters = /\p{L}+/u;     // כל אות (כל שפה)
const numbers = /\p{N}+/u;     // כל מספר
const currency = /\p{Sc}/u;    // סמלי מטבע

Python:

import regex  # הערה: דורש מודול 'regex', לא 're'

letters = regex.compile(r'\p{L}+')

קטגוריות Unicode נפוצות:

קטגוריה תיאור דוגמה
\p{L} אות "a", "字", "א"
\p{N} מספר "1", "①", "一"
\p{S} סמל "$", "©", "♥"
\p{Sc} סמל מטבע "$", "€", "₪"
\p{P} פיסוק ".", "!", "?"
\p{Z} מפריד רווח, טאב

סקריפטים של Unicode:

/\p{Script=Hebrew}/u    → מתאים לאותיות עבריות: "א", "ב", "ג"
/\p{Script=Greek}/u     → מתאים לאותיות יווניות: "α", "β", "γ"
/\p{Script=Cyrillic}/u  → מתאים לקירילית: "а", "б", "в"
/\p{Script=Han}/u       → מתאים לתווים סיניים

שלילה:

/\P{L}+/u   → מתאים לכל מה שאינו אות

משנים ודגלים

דגלים משנים איך דפוסי regex מפורשים.

דגל שם תיאור דוגמה
i חסר רגישות מתעלם מאותיות גדולות/קטנות /שלום/i מתאים "שלום"
g גלובלי מוצא את כל ההתאמות /חתול/g מוצא את כל "חתול"
m מרובה שורות ^ ו-$ מתאימים לתחילת/סוף שורה /^שלום/m
s Dotall . מתאים גם לשורה חדשה /a.b/s מתאים "a\nb"
u Unicode מאפשר תכונות Unicode /\p{L}+/u
x מורחב מתעלם מרווחים לבנים (free-spacing) מאפשר הערות
y דביק מתאים במיקום מדויק רק JavaScript

דוגמאות:

חסר רגישות (i):

/שלום/i.test('שלום')   // true

גלובלי (g):

'חתול כלב חתול'.match(/חתול/g)   // ["חתול", "חתול"]

מרובה שורות (m):

const text = 'שורה 1\nשורה 2';
/^שורה 2/m.test(text)   // true (בלי 'm': false)

Dotall (s):

/a.b/s.test('a\nb')   // true (בלי 's': false)

משנים בשורה

החל דגלים על חלק מהדפוס:

(?i)שלום       → "שלום" חסר רגישות
(?-i)עולם     → "עולם" רגיש לאותיות
(?i:שלום)      → רק "שלום" חסר רגישות

דפוסים מותנים

תחביר: (?(תנאי)נכון|לא נכון)

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

("|')?[^"'\r\n]*(?(1)\1)

פירוק:

  • ("|')? - לוכד אופציונלית מרכאה פותחת
  • [^"'\r\n]* - מתאים לתוכן
  • (?(1)\1) - אם קבוצה 1 התאימה (מרכאה פותחת), התאם את אותה מרכאה סוגרת

מתאים:

  • "שלום"
  • 'עולם'
  • בדיקה ✅ (ללא מרכאות)
  • "מעורב' ❌ (מרכאות לא תואמות)

הערות ב-Regex

הערות בשורה (?# הערה)

\d{3}(?# קידומת)-\d{3}(?# אמצעי)-\d{4}(?# מספר)

מצב Free-Spacing (דגל x)

מתעלם מרווחים לבנים ומאפשר הערות:

(?x)
  \d{3}     # קידומת
  -         # מפריד
  \d{3}     # אמצעי
  -         # מפריד
  \d{4}     # מספר

הרבה יותר קריא לדפוסים מורכבים!

סעיף זה מדגים כיצד להשתמש ב-regex ב-7 שפות תכנות פופולריות. לכל שפה יש את ה-API של regex שלה, אבל תחביר הדפוסים נשאר ברובו עקבי.

JavaScript / Node.js

יצירת דפוסי Regex

// סימון ליטרלי (הכי נפוץ)
const pattern1 = /\d{3}-\d{4}/;

// קונסטרוקטור (כשהדפוס דינמי)
const pattern2 = new RegExp('\\d{3}-\\d{4}');
// הערה: צריך לברוח מ-backslash במחרוזות

// עם דגלים
const pattern3 = /שלום/gi;  // גלובלי, חסר רגישות

מתודות String

// .match() - מוצא התאמות
const text = 'צור קשר: 123-4567 או 987-6543';
const matches = text.match(/\d{3}-\d{4}/g);
console.log(matches);  // ["123-4567", "987-6543"]

// .matchAll() - מקבל את כל ההתאמות עם קבוצות (ES2020)
const emailPattern = /([\w.-]+)@([\w.-]+\.[a-z]{2,})/gi;
const emails = 'admin@example.co.il, user@test.org';
for (const match of emails.matchAll(emailPattern)) {
  console.log(`משתמש: ${match[1]}, דומיין: ${match[2]}`);
}
// משתמש: admin, דומיין: example.co.il
// משתמש: user, דומיין: test.org

// .search() - מוצא מיקום של ההתאמה הראשונה
const pos = 'שלום עולם'.search(/עולם/);
console.log(pos);  // 5

// .replace() - מחליף התאמות
const phone = '(+972) 50 123 4567';
const cleaned = phone.replace(/[^\d]/g, '');
console.log(cleaned);  // "972501234567"

// .replaceAll() - מחליף את כל ההתאמות (ES2021)
const text2 = 'חתול כלב חתול';
const result = text2.replaceAll(/חתול/g, 'ציפור');
console.log(result);  // "ציפור כלב ציפור"

// .split() - מחלק לפי דפוס
const csv = 'תפוח,בננה, תפוז , ענבים';
const fruits = csv.split(/\s*,\s*/);
console.log(fruits);  // ["תפוח", "בננה", "תפוז", "ענבים"]

מתודות RegExp

// .test() - מחזיר בוליאני
const isEmail = /^[\w.-]+@[\w.-]+\.[a-z]{2,}$/i;
console.log(isEmail.test('user@example.co.il'));  // true

// .exec() - מחזיר פרטי התאמה (או null)
const pattern = /(\d{4})-(\d{2})-(\d{2})/;
const match = pattern.exec('תאריך: 2025-01-17');
if (match) {
  console.log(match[0]);  // "2025-01-17" (התאמה מלאה)
  console.log(match[1]);  // "2025" (קבוצה 1)
  console.log(match[2]);  // "01" (קבוצה 2)
  console.log(match[3]);  // "17" (קבוצה 3)
}

קבוצות עם שם (ES2018+)

const pattern = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
const match = '2025-01-17'.match(pattern);

console.log(match.groups.year);   // "2025"
console.log(match.groups.month);  // "01"
console.log(match.groups.day);    // "17"

// הפניות אחורה עם שם
const dupeWord = /\b(?<word>\w+)\s+\k<word>\b/i;
console.log(dupeWord.test('שלום שלום'));  // true

תמיכת Unicode (ES2018+)

// מתאים לכל אות (כולל מודגשות, סיניות, ערביות וכו')
const letters = /\p{L}+/u;
console.log(letters.test('קפה'));   // true
console.log(letters.test('你好'));    // true

// מתאים לאמוג'י
const emoji = /\p{Emoji}/u;
console.log(emoji.test('שלום 👋'));  // true

Python

המודול re

import re

# קימפול דפוס (מומלץ לשימוש חוזר)
pattern = re.compile(r'\d{3}-\d{4}')

# או שימוש ישיר
re.search(r'\d{3}-\d{4}', 'התקשר 123-4567')

פונקציות ליבה

import re

# re.search() - מוצא התאמה ראשונה
match = re.search(r'\d{3}-\d{4}', 'צור קשר: 123-4567 או 987-6543')
if match:
    print(match.group())  # "123-4567"
    print(match.start())  # 10 (מיקום)
    print(match.end())    # 18

# re.match() - מתאים בהתחלת המחרוזת
match = re.match(r'\d+', '123 רחוב הרצל')
print(match.group() if match else None)  # "123"

match = re.match(r'\d+', 'רחוב הרצל 123')
print(match)  # None (לא מתחיל בספרה)

# re.fullmatch() - מתאים לכל המחרוזת
result = re.fullmatch(r'\d{3}-\d{4}', '123-4567')
print(bool(result))  # True

result = re.fullmatch(r'\d{3}-\d{4}', 'התקשר 123-4567')
print(bool(result))  # False (טקסט נוסף)

# re.findall() - מוצא את כל ההתאמות (מחזיר רשימה)
text = 'מחירים: ₪10, ₪25, ₪100'
prices = re.findall(r'₪(\d+)', text)
print(prices)  # ['10', '25', '100']

# re.finditer() - מוצא את כל ההתאמות (מחזיר איטרטור)
for match in re.finditer(r'₪(\d+)', text):
    print(f'נמצא ₪{match.group(1)} במיקום {match.start()}')
# נמצא ₪10 במיקום 8
# נמצא ₪25 במיקום 13
# נמצא ₪100 במיקום 18

# re.sub() - מחליף התאמות
phone = '(+972) 50 123 4567'
cleaned = re.sub(r'[^\d]', '', phone)
print(cleaned)  # "972501234567"

# re.split() - מחלק לפי דפוס
csv = 'תפוח,בננה, תפוז , ענבים'
fruits = re.split(r'\s*,\s*', csv)
print(fruits)  # ['תפוח', 'בננה', 'תפוז', 'ענבים']

קבוצות וקבוצות עם שם

import re

# קבוצות ממוספרות
pattern = r'(\d{4})-(\d{2})-(\d{2})'
match = re.search(pattern, 'תאריך: 2025-01-17')
if match:
    print(match.group(0))  # "2025-01-17" (התאמה מלאה)
    print(match.group(1))  # "2025"
    print(match.group(2))  # "01"
    print(match.group(3))  # "17"
    print(match.groups())  # ('2025', '01', '17')

# קבוצות עם שם (?P<name>...)
pattern = r'(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})'
match = re.search(pattern, '2025-01-17')
if match:
    print(match.group('year'))    # "2025"
    print(match.group('month'))   # "01"
    print(match.group('day'))     # "17"
    print(match.groupdict())      # {'year': '2025', 'month': '01', 'day': '17'}

דגלים

import re

# חסר רגישות
re.search(r'שלום', 'שלום', re.IGNORECASE)  # או re.I

# מרובה שורות (^ ו-$ מתאימים לתחילת/סוף שורה)
re.search(r'^שורה 2', 'שורה 1\nשורה 2', re.MULTILINE)  # או re.M

# Dotall (. מתאים לשורה חדשה)
re.search(r'a.b', 'a\nb', re.DOTALL)  # או re.S

# Verbose (מצב free-spacing עם הערות)
pattern = re.compile(r'''
    \d{3}     # קידומת
    -         # מפריד
    \d{3}     # אמצעי
    -         # מפריד
    \d{4}     # מספר
''', re.VERBOSE)  # או re.X

# שילוב דגלים עם |
pattern = re.compile(r'שלום', re.IGNORECASE | re.MULTILINE)

החלפה עם פונקציות

import re

# שימוש בפונקציה להחלפות דינמיות
def double_number(match):
    num = int(match.group())
    return str(num * 2)

text = 'יש לי 5 תפוחים ו-10 תפוזים'
result = re.sub(r'\d+', double_number, text)
print(result)  # "יש לי 10 תפוחים ו-20 תפוזים"

# עם קבוצות עם שם
def format_name(match):
    return f"{match.group('last').upper()}, {match.group('first')}"

pattern = r'(?P<first>\w+)\s+(?P<last>\w+)'
text = 'דוד כהן'
result = re.sub(pattern, format_name, text)
print(result)  # "כהן, דוד"

PHP

פונקציות PCRE

<?php

// preg_match() - מוצא התאמה ראשונה
$pattern = '/\d{3}-\d{4}/';
$text = 'צור קשר: 123-4567 או 987-6543';

if (preg_match($pattern, $text, $matches)) {
    echo $matches[0];  // "123-4567"
}

// preg_match_all() - מוצא את כל ההתאמות
preg_match_all('/\d{3}-\d{4}/', $text, $matches);
print_r($matches[0]);  // ["123-4567", "987-6543"]

// preg_replace() - מחליף התאמות
$phone = '(+972) 50 123 4567';
$cleaned = preg_replace('/[^\d]/', '', $phone);
echo $cleaned;  // "972501234567"

// preg_split() - מחלק לפי דפוס
$csv = 'תפוח,בננה, תפוז , ענבים';
$fruits = preg_split('/\s*,\s*/', $csv);
print_r($fruits);  // ["תפוח", "בננה", "תפוז", "ענבים"]

// preg_grep() - מסנן מערך לפי דפוס
$words = ['תפוח', 'בננה', 'אבטיח', 'אגס'];
$aWords = preg_grep('/^א/', $words);
print_r($aWords);  // ["אבטיח", "אגס"]
?>

קבוצות עם שם

<?php
$pattern = '/(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})/';
$text = '2025-01-17';

if (preg_match($pattern, $text, $matches)) {
    echo $matches['year'];   // "2025"
    echo $matches['month'];  // "01"
    echo $matches['day'];    // "17"
}
?>

משנים (דגלים)

<?php
// i - חסר רגישות
preg_match('/שלום/i', 'שלום');  // מתאים

// m - מרובה שורות
preg_match('/^שורה 2/m', "שורה 1\nשורה 2");  // מתאים

// s - Dotall (. מתאים לשורה חדשה)
preg_match('/a.b/s', "a\nb");  // מתאים

// x - Free-spacing (מתעלם מרווחים לבנים)
$pattern = '/
    \d{3}     # קידומת
    -         # מפריד
    \d{3}     # אמצעי
    -         # מפריד
    \d{4}     # מספר
/x';

// u - תמיכת UTF-8
preg_match('/\w+/u', 'קפה');  // מתאים (כולל ה)

// שילוב משנים
preg_match('/שלום/imu', $text);
?>

החלפה עם Callback

<?php
$text = 'יש לי 5 תפוחים ו-10 תפוזים';

$result = preg_replace_callback('/\d+/', function($matches) {
    return (int)$matches[0] * 2;
}, $text);

echo $result;  // "יש לי 10 תפוחים ו-20 תפוזים"
?>

C# (.NET)

מחלקת Regex

using System;
using System.Text.RegularExpressions;

// מתודות סטטיות (שימוש פשוט)
string text = "צור קשר: 123-4567 או 987-6543";
Match match = Regex.Match(text, @"\d{3}-\d{4}");
if (match.Success)
{
    Console.WriteLine(match.Value);  // "123-4567"
}

// מוצא את כל ההתאמות
MatchCollection matches = Regex.Matches(text, @"\d{3}-\d{4}");
foreach (Match m in matches)
{
    Console.WriteLine(m.Value);
}
// פלט:
// 123-4567
// 987-6543

// החלפה
string phone = "(+972) 50 123 4567";
string cleaned = Regex.Replace(phone, @"[^\d]", "");
Console.WriteLine(cleaned);  // "972501234567"

// חלוקה
string csv = "תפוח,בננה, תפוז , ענבים";
string[] fruits = Regex.Split(csv, @"\s*,\s*");
// ["תפוח", "בננה", "תפוז", "ענבים"]

Regex קומפיילד (ביצועים טובים יותר)

using System.Text.RegularExpressions;

// קימפול לשימוש חוזר (הרבה יותר מהיר לשימוש חוזר)
Regex pattern = new Regex(@"\d{3}-\d{4}", RegexOptions.Compiled);

string text = "צור קשר: 123-4567";
Match match = pattern.Match(text);
if (match.Success)
{
    Console.WriteLine(match.Value);
}

RegexOptions (דגלים)

using System.Text.RegularExpressions;

// חסר רגישות
Regex.IsMatch("שלום", "שלום", RegexOptions.IgnoreCase);

// מרובה שורות
Regex.Match("שורה 1\nשורה 2", "^שורה 2", RegexOptions.Multiline);

// Singleline (. מתאים לשורה חדשה)
Regex.Match("a\nb", "a.b", RegexOptions.Singleline);

// קומפיילד (ביצועים טובים יותר)
var pattern = new Regex(@"\d+", RegexOptions.Compiled);

// שילוב אפשרויות
var opts = RegexOptions.IgnoreCase | RegexOptions.Multiline;
Regex.Match(text, pattern, opts);

קבוצות עם שם

using System;
using System.Text.RegularExpressions;

string pattern = @"(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})";
Match match = Regex.Match("2025-01-17", pattern);

if (match.Success)
{
    Console.WriteLine(match.Groups["year"].Value);   // "2025"
    Console.WriteLine(match.Groups["month"].Value);  // "01"
    Console.WriteLine(match.Groups["day"].Value);    // "17"
}

החלפה עם MatchEvaluator

using System;
using System.Text.RegularExpressions;

string text = "יש לי 5 תפוחים ו-10 תפוזים";

string result = Regex.Replace(text, @"\d+", match =>
{
    int num = int.Parse(match.Value);
    return (num * 2).ToString();
});

Console.WriteLine(result);  // "יש לי 10 תפוחים ו-20 תפוזים"

Java

מחלקות Pattern ו-Matcher

import java.util.regex.Pattern;
import java.util.regex.Matcher;

// קימפול דפוס
Pattern pattern = Pattern.compile("\\d{3}-\\d{4}");
String text = "צור קשר: 123-4567 או 987-6543";

// יצירת matcher
Matcher matcher = pattern.matcher(text);

// מוצא התאמה ראשונה
if (matcher.find()) {
    System.out.println(matcher.group());  // "123-4567"
}

// מוצא את כל ההתאמות
matcher.reset();  // איפוס להתחלה
while (matcher.find()) {
    System.out.println(matcher.group());
}
// פלט:
// 123-4567
// 987-6543

מתודות String

// matches() - בודק אם כל המחרוזת מתאימה
boolean isPhone = "123-4567".matches("\\d{3}-\\d{4}");
System.out.println(isPhone);  // true

// replaceAll() - מחליף את כל ההתאמות
String phone = "(+972) 50 123 4567";
String cleaned = phone.replaceAll("[^\\d]", "");
System.out.println(cleaned);  // "972501234567"

// replaceFirst() - מחליף התאמה ראשונה
String text = "חתול כלב חתול";
String result = text.replaceFirst("חתול", "ציפור");
System.out.println(result);  // "ציפור כלב חתול"

// split() - מחלק לפי דפוס
String csv = "תפוח,בננה, תפוז , ענבים";
String[] fruits = csv.split("\\s*,\\s*");
// ["תפוח", "בננה", "תפוז", "ענבים"]

דגלי Pattern

import java.util.regex.Pattern;

// חסר רגישות
Pattern pattern = Pattern.compile("שלום", Pattern.CASE_INSENSITIVE);

// מרובה שורות
Pattern.compile("^שורה 2", Pattern.MULTILINE);

// Dotall (. מתאים לשורה חדשה)
Pattern.compile("a.b", Pattern.DOTALL);

// הערות (free-spacing)
Pattern.compile("""
    \\d{3}     # קידומת
    -          # מפריד
    \\d{3}     # אמצעי
    -          # מפריד
    \\d{4}     # מספר
    """, Pattern.COMMENTS);

// שילוב דגלים
int flags = Pattern.CASE_INSENSITIVE | Pattern.MULTILINE;
Pattern.compile("pattern", flags);

קבוצות עם שם

import java.util.regex.Pattern;
import java.util.regex.Matcher;

Pattern pattern = Pattern.compile("(?<year>\\d{4})-(?<month>\\d{2})-(?<day>\\d{2})");
Matcher matcher = pattern.matcher("2025-01-17");

if (matcher.find()) {
    System.out.println(matcher.group("year"));   // "2025"
    System.out.println(matcher.group("month"));  // "01"
    System.out.println(matcher.group("day"));    // "17"
}

החלפה מתקדמת

import java.util.regex.Pattern;
import java.util.regex.Matcher;

String text = "יש לי 5 תפוחים ו-10 תפוזים";
Pattern pattern = Pattern.compile("\\d+");
Matcher matcher = pattern.matcher(text);

StringBuffer result = new StringBuffer();
while (matcher.find()) {
    int num = Integer.parseInt(matcher.group());
    matcher.appendReplacement(result, String.valueOf(num * 2));
}
matcher.appendTail(result);

System.out.println(result);  // "יש לי 10 תפוחים ו-20 תפוזים"

Go (Golang)

החבילה regexp

package main

import (
    "fmt"
    "regexp"
)

func main() {
    // קימפול דפוס
    pattern := regexp.MustCompile(`\d{3}-\d{4}`)
    text := "צור קשר: 123-4567 או 987-6543"

    // מוצא התאמה ראשונה
    match := pattern.FindString(text)
    fmt.Println(match)  // "123-4567"

    // מוצא את כל ההתאמות
    matches := pattern.FindAllString(text, -1)
    fmt.Println(matches)  // [123-4567 987-6543]

    // בודק אם מתאים
    isMatch := pattern.MatchString("123-4567")
    fmt.Println(isMatch)  // true

    // מחליף הכל
    phone := "(+972) 50 123 4567"
    cleaned := regexp.MustCompile(`[^\d]`).ReplaceAllString(phone, "")
    fmt.Println(cleaned)  // "972501234567"

    // מחלק
    csv := "תפוח,בננה, תפוז , ענבים"
    fruits := regexp.MustCompile(`\s*,\s*`).Split(csv, -1)
    fmt.Println(fruits)  // [תפוח בננה תפוז ענבים]
}

Submatch (קבוצות)

package main

import (
    "fmt"
    "regexp"
)

func main() {
    pattern := regexp.MustCompile(`(\d{4})-(\d{2})-(\d{2})`)
    text := "תאריך: 2025-01-17"

    // FindStringSubmatch מחזיר [מלא, קבוצה1, קבוצה2, ...]
    matches := pattern.FindStringSubmatch(text)
    if matches != nil {
        fmt.Println(matches[0])  // "2025-01-17" (התאמה מלאה)
        fmt.Println(matches[1])  // "2025" (קבוצה 1)
        fmt.Println(matches[2])  // "01" (קבוצה 2)
        fmt.Println(matches[3])  // "17" (קבוצה 3)
    }

    // FindAllStringSubmatch לכל ההתאמות
    text2 := "תאריכים: 2025-01-17 ו-2024-12-31"
    allMatches := pattern.FindAllStringSubmatch(text2, -1)
    for _, match := range allMatches {
        fmt.Printf("שנה: %s, חודש: %s, יום: %s\n", match[1], match[2], match[3])
    }
    // שנה: 2025, חודש: 01, יום: 17
    // שנה: 2024, חודש: 12, יום: 31
}

קבוצות עם שם

package main

import (
    "fmt"
    "regexp"
)

func main() {
    pattern := regexp.MustCompile(`(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})`)
    text := "2025-01-17"

    match := pattern.FindStringSubmatch(text)
    if match != nil {
        // מקבל אינדקסים של קבוצות עם שם
        names := pattern.SubexpNames()
        result := make(map[string]string)
        for i, name := range names {
            if i != 0 && name != "" {
                result[name] = match[i]
            }
        }
        fmt.Println(result["year"])   // "2025"
        fmt.Println(result["month"])  // "01"
        fmt.Println(result["day"])    // "17"
    }
}

החלפה עם פונקציות

package main

import (
    "fmt"
    "regexp"
    "strconv"
)

func main() {
    text := "יש לי 5 תפוחים ו-10 תפוזים"
    pattern := regexp.MustCompile(`\d+`)

    result := pattern.ReplaceAllStringFunc(text, func(s string) string {
        num, _ := strconv.Atoi(s)
        return strconv.Itoa(num * 2)
    })

    fmt.Println(result)  // "יש לי 10 תפוחים ו-20 תפוזים"
}

Ruby

ליטרלים של Regex

# סימון ליטרלי
pattern = /\d{3}-\d{4}/

# עם דגלים
pattern_ci = /שלום/i  # חסר רגישות
pattern_multi = /^שורה/m  # מרובה שורות

# קונסטרוקטור (לדפוסים דינמיים)
pattern = Regexp.new('\d{3}-\d{4}')

מתודות String

text = 'צור קשר: 123-4567 או 987-6543'

# match() - מחזיר MatchData או nil
match = text.match(/\d{3}-\d{4}/)
if match
  puts match[0]  # "123-4567"
end

# scan() - מוצא את כל ההתאמות
matches = text.scan(/\d{3}-\d{4}/)
puts matches  # ["123-4567", "987-6543"]

# =~ אופרטור - מחזיר אינדקס של ההתאמה הראשונה
index = text =~ /\d{3}-\d{4}/
puts index  # 10

# sub() - מחליף התאמה ראשונה
result = 'חתול כלב חתול'.sub(/חתול/, 'ציפור')
puts result  # "ציפור כלב חתול"

# gsub() - מחליף את כל ההתאמות
phone = '(+972) 50 123 4567'
cleaned = phone.gsub(/[^\d]/, '')
puts cleaned  # "972501234567"

# split() - מחלק לפי דפוס
csv = 'תפוח,בננה, תפוז , ענבים'
fruits = csv.split(/\s*,\s*/)
puts fruits  # ["תפוח", "בננה", "תפוז", "ענבים"]

קבוצות לכידה

pattern = /(\d{4})-(\d{2})-(\d{2})/
match = '2025-01-17'.match(pattern)

if match
  puts match[0]  # "2025-01-17" (התאמה מלאה)
  puts match[1]  # "2025" (קבוצה 1)
  puts match[2]  # "01" (קבוצה 2)
  puts match[3]  # "17" (קבוצה 3)
end

קבוצות עם שם

pattern = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/
match = '2025-01-17'.match(pattern)

if match
  puts match[:year]   # "2025"
  puts match[:month]  # "01"
  puts match[:day]    # "17"
end

החלפה עם בלוקים

text = 'יש לי 5 תפוחים ו-10 תפוזים'

result = text.gsub(/\d+/) { |num| (num.to_i * 2).to_s }
puts result  # "יש לי 10 תפוחים ו-20 תפוזים"

# עם קבוצות עם שם
pattern = /(?<first>\w+)\s+(?<last>\w+)/
text = 'דוד כהן'

result = text.gsub(pattern) do |match|
  m = Regexp.last_match
  "#{m[:last].upcase}, #{m[:first]}"
end
puts result  # "כהן, דוד"

דגלים

# i - חסר רגישות
/שלום/i.match('שלום')  # מתאים

# m - מרובה שורות (. מתאים לשורה חדשה)
/a.b/m.match("a\nb")  # מתאים

# x - Free-spacing (מתעלם מרווחים לבנים)
pattern = /
  \d{3}     # קידומת
  -         # מפריד
  \d{3}     # אמצעי
  -         # מפריד
  \d{4}     # מספר
/x

# o - קימפול פעם אחת (אופטימיזציה)
pattern = /\d+/o

החיפוש והחלפה של Visual Studio Code (Ctrl/Cmd+H) תומך ב-regex עם יכולות טרנספורמציה חזקות. סעיף זה מציג 28 דוגמאות מעשיות שמפתחים משתמשים בהן כל יום.

גישה לחיפוש והחלפה

קיצורי מקלדת:

  • חיפוש: Ctrl+F (Windows/Linux) / Cmd+F (Mac)
  • החלפה: Ctrl+H (Windows/Linux) / Cmd+H (Mac)
  • הפעלת Regex: לחץ על כפתור .* או הקש Alt+R

טיפים:

  • השתמש ב-Ctrl+Enter (Cmd+Enter) כדי להחליף הכל
  • תצוגה מקדימה של התאמות לפני החלפה (מודגשות בצהוב)
  • השתמש ב-F3 / Shift+F3 לניווט בין התאמות

טרנספורמציות אותיות גדולות/קטנות

VS Code תומך ברצפים מיוחדים להחלפה להמרת אותיות:

רצף השפעה דוגמה
\l אות קטנה לתו הבא \l
\u אות גדולה לתו הבא \u
\L אות קטנה לכל התווים הבאים \L
\U אות גדולה לכל התווים הבאים \U
\E סיום טרנספורמציית אותיות \U\E

דוגמה 1: הפוך לאות גדולה בתחילת מילה

חיפוש:

\b(\w)(\w*)

החלפה:

\u$1$2

לפני:

שלום עולם

אחרי:

שלום עולם

סעיף זה מספק מעל 25 דפוסי regex מוכנים לשימוש.

אימות אימייל

^[\w.-]+@[\w.-]+\.[a-z]{2,}$

מספרי טלפון (ישראל)

^(\+?972)?[-.\s]?\(?([0-9]{2,3})\)?[-.\s]?([0-9]{3})[-.\s]?([0-9]{4})$

תאריכים (ISO 8601)

^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$

URL

^https?://(?:www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b

כתובות IPv4

^(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)$

צבעי Hex

^#?([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$

סיסמה חזקה

^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$

שם משתמש (3-16 תווים)

^[a-zA-Z0-9_-]{3,16}$

UUID v4

^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$

ועוד 15+ דפוסים עם תיעוד מלא!

יישומי regex מהעולם האמיתי בפיתוח.

אימות טפסים

const validators = {
  email: /^[\w.-]+@[\w.-]+\.[a-z]{2,}$/i,
  phone: /^\(?\d{2,3}\)?[-.\s]?\d{3}[-.\s]?\d{4}$/
};

חילוץ נתונים

חילוץ אימיילים מטקסט:

import re
emails = re.findall(r'[\w.-]+@[\w.-]+\.[a-z]{2,}', text)

ניתוח לוגים

pattern = r'(?P<ip>[\d.]+).+(?P<status>\d{3})'

Refactoring קוד

המרת קריאות API ישנות ב-VS Code:

חיפוש: apiClient\.get\('([^']+)'\)
החלפה: fetch('$1').then(r => r.json())

טעויות נפוצות

1. שכחת לברוח מתווים מיוחדים

❌ שגוי: file.txt
✅ נכון: file\.txt

2. חמדני לעומת עצלני

❌ חמדני: <.*> מתאים לכל <div>טקסט</div>
✅ עצלני: <.*?> מתאים ל-<div> ו-</div> בנפרד

3. אי שימוש בעוגנים

/\d{3}/ מתאים "123" ב"abc123def"
/^\d{3}$/ מתאים רק בדיוק ל"123"

טיפים לביצועים

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

ניפוי שגיאות

  1. בדוק ב-regex101.com
  2. השתמש במצב verbose עם הערות
  3. חלק דפוסים מורכבים לחלקים
  4. בדוק מקרי קצה

כלים מקוונים

בודקי Regex

  • regex101.com - הבודק הטוב ביותר עם הסברים
  • regexr.com - בונה ויזואלי של regex
  • regexpal.com - בדיקה פשוטה ומהירה

כלי ויזואליזציה

  • debuggex.com - דיאגרמות railroad
  • regexper.com - כלי ויזואלי

משאבי למידה

  • regexone.com - שיעורים אינטראקטיביים
  • regexlearn.com - מדריך צעד אחר צעד
  • regular-expressions.info - תיעוד

תוספים ל-IDE

  • Regex Previewer (VS Code)
  • Regex Tester (VS Code)

מחלקות תווים

דפוס מתאים ל
\d ספרה [0-9]
\w מילה [a-zA-Z0-9_]
\s רווח לבן
. כל תו

כמתים

דפוס משמעות
* 0 או יותר
+ 1 או יותר
? 0 או 1
{n} בדיוק n

עוגנים

דפוס משמעות
^ תחילת שורה
$ סוף שורה
\b גבול מילה

דגלים

דגל משמעות
i חסר רגישות
g גלובלי
m מרובה שורות
s Dotall

שאלות כלליות

ש: מה ההבדל בין כמתים חמדניים לעצלניים?

ת: חמדני מתאים למקסימום האפשרי. עצלני (*?, +?) מתאים למינימום האפשרי.

ש: איך אני מתאים לנקודה ליטרלית?

ת: ברח ממנה עם backslash: \.

ש: מה זה backtracking קטסטרופלי?

ת: כאשר regex מנסה הרבה צירופים, גורם לאיטיות. הימנע מכמתים מקוננים כמו (a+)+.

ש: האם regex יכול לאמת אימייל בצורה מושלמת?

ת: לא. השתמש ב-regex לפורמט בסיסי, ואז אמת באמצעות אימייל.

ש: איך אני מתאים על פני מספר שורות?

ת: השתמש בדגל s, או השתמש ב-[\s\S]* במקום .*.

ספציפי ל-VS Code

ש: איך אני מחליף עם אותיות גדולות ב-VS Code?

ת: השתמש ב-\u (אות גדולה הבאה), \U (אות גדולה לכל).

ש: האם אני יכול להשתמש ב-regex בחיפוש קבצים ב-VS Code?

ת: כן! הקש Ctrl+Shift+F והפעל regex (Alt+R).

תוסף Chrome Regex Data Extractor

ה-Regex Data Extractor שלנו עוזר לכם לחלץ נתונים מדפי אינטרנט באמצעות הדפוסים מהמדריך הזה.

תכונות עיקריות

  • ספריית דפוסים: דפוסים מובנים מראש
  • בדיקה בזמן אמת: בדוק regex בכל דף אינטרנט
  • ייצוא מרובה פורמטים: CSV, JSON, Excel, PDF
  • חילוץ באצווה: חילוץ מדפים מרובים

דוגמה: חילוץ אימיילים

  1. התקן את Regex Data Extractor
  2. נווט לכל דף אינטרנט
  3. לחץ על אייקון התוסף
  4. הכנס דפוס: [\w.-]+@[\w.-]+\.[a-z]{2,}
  5. לחץ "חלץ"
  6. ייצא ל-CSV/JSON

דוגמה: חילוץ מחירים

דפוס: ₪([0-9]{1,3}(?:\.?[0-9]{3})*,?[0-9]{2})
לוכד: ₪1,234.56, ₪99.99

טיפים מקצועיים

  • שמור דפוסים בשימוש תדיר
  • השתמש בקבוצות עם שם לנתונים מובנים
  • בדוק דפוסים קודם
  • ייצא לניתוח נתונים

קבל את Regex Data Extractor →

regexביטויים רגולרייםדף עזרדפוסיםמדריךvs codepythonjavascriptphp

Last updated: 16 בינואר 2025