› كل الدروس
الدرس 11 من 12 26 دقيقة

Regular Expressions

دوّر على نمط مش على كلمة

الفكرة باختصار

Regex لغة صغيرة بتوصف شكل string اللي بتدوّر عليه — مش string نفسه.

بعد الدرس ده هتعرف

  • تفهم إمتى تحتاج regex وإمتى لأ
  • تقرا الرموز الأساسية
  • تستخرج أرقام وإيميلات من string
  • تبني نمط بسيط بنفسك
1

شوف الفكرة الأول

قبل أي code — افهم بيحصل إيه

2

الشرح

فكرة واحدة في كل خطوة

1

المشكلة اللي بيحلّها

عايز تطلّع كل الأرقام من السطر ده: "الغرفة 12 فيها 3 مرضى و 2 ممرضين".

بـ .find() و .split() هتكتب 20 سطر وهتنسى حالة.

بـ regex بتقول: «هاتلي كل حتة فيها رقم أو أكتر» — سطر واحد.

بس خد بالك: لو بتدوّر على كلمة ثابتة، in و .find() أبسط وأوضح. regex للأنماط بس.

2

الرموز الأساسية

\d رقم واحد (0-9) · \w حرف أو رقم أو _ · \s مسافة

+ واحد أو أكتر · * صفر أو أكتر · ? صفر أو واحد

. أي حرف · ^ بداية string · $ نهاية string

[abc] أي حرف من دول · [0-9] أي رقم · [^x] أي حاجة غير x

يعني \d+ معناها «رقم واحد أو أكتر ورا بعض» — وده اللي بيمسك 12 و 3 و 2.

3

أمثلة مقرّبة

\d+ → أي رقم: 12 · 2026 · 7

\d+\.\d+ → رقم عشري: 38.2 (لاحظ \. عشان النقطة الحقيقية)

\S+@\S+ → إيميل مبسّط: أي حاجة، ثم @، ثم أي حاجة

^ALERT → السطور اللي بتبدأ بكلمة ALERT

[A-Z]\w+ → كلمة بتبدأ بحرف كبير

4

الاستخدام في Python

بتستورد library بـ import re، وبعدين:

re.findall(pattern, text) → list بكل اللي اتطابق
re.search(pattern, text) → أول تطابق أو None
re.sub(pattern, new, text) → استبدال

دايمًا حُط r قبل النمط: r"\d+". من غيرها Python هتفهم \d غلط.

جرّب النمط بنفسك في المختبر التفاعلي تحت

5

النمط العملي: استخراج أرقام

ده أكتر استخدام هتعمله: عندك سطر string فيه أرقام، عايز تطلّعها وتحسب عليها.

1import re
2line = "الغرفة 12 فيها 3 مرضى"
3nums = re.findall(r"\d+", line)
4# nums = ["12", "3"]
5total = sum(int(n) for n in nums)


لاحظ إن النتيجة strings مش أرقام — لازم int().

6

امسك المجموعات

الأقواس () في النمط بتقول «الجزء ده عايزه لوحده».

(\w+)@(\w+) على "ali@borg" بتدّيك ("ali", "borg") — الاسم والدومين منفصلين.

دي اللي بتخلّي regex أقوى من مجرد بحث: بتفصل الأجزاء وإنت بتدوّر.

7

الكميات — قُل عايز كام بالظبط

الرموز + و * و ? بتقول «كتير» أو «شوية». وفيه طريقة تقول العدد بالظبط:

\d{4} → أربع أرقام بالظبط (سنة مثلاً)
\d{2,4} → من رقمين لأربعة
\d{3,} → تلاتة أو أكتر

دي اللي بتفرّق بين «أي أرقام» وبين «رقم قومي من 14 رقم».

بص على الناتج كويس: \d{4} مسكت 1234 من جوّه 1234567 كمان! النمط بيدوّر في أي مكان — عشان كده التحقّق الحقيقي بيحتاج ^ و $.

Python
1import re
2
3text = "year 2026 and code 12 and number 1234567"
4print(re.findall(r"\d{4}", text))
5print(re.findall(r"\d{2,3}", text))
الناتج
['2026', '1234']
['202', '12', '123', '456']
8

findall و search و match — إيه الفرق؟

findall → list بكل التطابقات. بتستخدمها لما تكون عايز كل الحاجات.

search → أول تطابق بس، وبترجّع object فيه تفاصيل (أو None). بتستخدمها لما تسأل «هو موجود؟» أو عايز الأول بس.

match → زي search بس بتفحص بداية string بس.

القاعدة العملية: عايز تعد أو تجمّع → findall. عايز تفحص أو تفصل أجزاء → search.

لاحظ في الناتج إن \d+ شافت 39.2 على إنها رقمين (39 و 2) — لأن النقطة مش رقم. عشان تمسك العشري كله لازم \d+\.\d+.

Python
1import re
2
3line = "ALERT 39.2 at ROOM12"
4print(re.findall(r"\d+", line))
5
6m = re.search(r"(\d+)\.(\d+)", line)
7if m:
8 print(m.group(0), "→", m.group(1), m.group(2))
الناتج
['39', '2', '12']
39.2 → 39 2
9

أنماط هتحتاجها فعلاً

دي أنماط جاهزة تنفعك في شغل حقيقي — افهمها وما تحفظهاش:

^\d{11}$ → رقم موبايل مصري (11 رقم بالظبط، ومفيش حاجة تانية)
\d{4}-\d{2}-\d{2} → تاريخ بشكل 2026-10-01
\S+@\S+\.\S+ → إيميل مبسّط
^\s*$ → سطر فاضي أو مسافات بس

^ و $ مهمين جدًا في التحقّق: من غيرهم \d{11} هتقبل رقم من 20 رقم لأن فيه 11 رقم جواه.

Python
1import re
2
3phones = ["01012345678", "0101234", "010123456789"]
4for p in phones:
5 ok = re.search(r"^\d{11}$", p)
6 print(p, "+" if ok else "-")
الناتج
01012345678 +
0101234 -
010123456789 -
10

التنظيف بـ re.sub

regex مش للبحث بس — كمان بتنضّف.

re.sub(pattern, replacement, string) بتستبدل كل التطابقات وبترجّع string جديد.

أشهر استخدام: توحيد المسافات. \s+ معناها «مسافة واحدة أو أكتر» — فبتحوّل أي عدد مسافات أو تابات لمسافة واحدة.

Python
1import re
2
3raw = " name: Ahmed Abdelrahman "
4clean = re.sub(r"\s+", " ", raw).strip()
5print(clean)
6print(re.sub(r"[0-9]", "#", "code 2026 num 7"))
الناتج
name: Ahmed Abdelrahman
code #### num #
3

وده كمان شوفه متحرك

الفكرة دي أسهل ما تتشاف من ما تتقرا

4

أمثلة محلولة

شوف إزاي بنفكّر قبل ما نكتب

مثال 1

طلّع كل الأرقام من سطر

المطلوب: من "الغرفة 12 فيها 3 مرضى و 2 ممرضين" هات كل الأرقام واجمعها.

نفكّر إزاي؟

  1. 1الشكل اللي بدوّر عليه: رقم واحد أو أكتر ورا بعض → \d+
  2. 2findall بترجّع كل التطابقات في list
  3. 3الناتج strings — لازم int() قبل الجمع
مثال 2

الأرقام العشرية بس

المطلوب: من سجل قراءات، هات values اللي فيها فاصلة عشرية بس.

نفكّر إزاي؟

  1. 1رقم، بعديه نقطة حقيقية، بعديها رقم
  2. 2النقطة في regex معناها «أي حرف» → لازم \. للنقطة نفسها
  3. 3النمط بيبقى \d+\.\d+
مثال 3

الإيميلات في string

المطلوب: هات كل الإيميلات من جملة.

نفكّر إزاي؟

  1. 1الإيميل = حاجة، بعدين @، بعدين حاجة
  2. 2\S معناها أي حرف مش مسافة
  3. 3فالنمط المبسّط: \S+@\S+
مثال 4

امسك الأجزاء بالمجموعات

المطلوب: من إيميل، اطلّع اسم المستخدم والدومين كل واحد لوحده.

نفكّر إزاي؟

  1. 1الأقواس () بتقول «الجزء ده عايزه منفصل»
  2. 2search بترجّع object تطابق أو None
  3. 3.group(1) أول مجموعة و .group(2) التانية
مثال 5

فلترة سطور بالبداية

المطلوب: من سجل، خد سطور التنبيه بس وطلّع القراءة منها.

نفكّر إزاي؟

  1. 1^ معناها «بداية string»
  2. 2أفلتر الأول بـ search
  3. 3وبعدين أطلّع الرقم العشري من السطر المطابق
مثال 6

إخفاء الأرقام الحسّاسة

المطلوب: استبدل كل رقم في string بنجمة قبل ما تعرضه.

نفكّر إزاي؟

  1. 1re.sub(pattern, replacement, string) بتستبدل كل التطابقات
  2. 2\d رقم واحد → كل رقم هيتحوّل لنجمة
  3. 3string الأصلي ما بيتغيّرش — بترجّع string جديد
5

ورقة مراجعة

ارجعلها وإنت بتحل — مش محتاج تحفظها

رموز Regex
الحاجةمعناهامثالالناتج
\dرقم واحدr"\d"5
\wحرف أو رقم أو _r"\w+"ali_2026
\sمسافةr"a\sb"a b
\Sأي حاجة مش مسافةr"\S+@\S+"a@b.com
.أي حرفr"a.c"abc / a1c
\.نقطة حقيقيةr"\d+\.\d+"38.9
+واحد أو أكترr"\d+"2026
*صفر أو أكترr"ab*"a / ab / abb
?صفر أو واحدr"colou?r"color / colour
^بداية stringr"^ALERT"السطور اللي بتبدأ كده
$نهاية stringr"\.eg$"اللي بتنتهي كده
[abc]أي حرف من دولr"[aeiou]"حرف متحرّك
[0-9]أي رقم (زي \d)r"[0-9]+"12
( )مجموعة بتتمسك لوحدهاr"(\w+)@"الاسم قبل @
re.findallكل التطابقات في listre.findall(r"\d+", s)['1', '2']
re.searchأول تطابق أو Nonere.search(r"a", s)object تطابق
re.subاستبدالre.sub(r"\d", "*", s)string جديد
r"..."raw string — إلزاميr"\d+"الباك سلاش بيوصل زي ما هو
6

نفس الشغل من غير regex

شوفه بيشتغل سطر سطر

شغّل code خطوة خطوة

عشان تقدّر regex، شوف الشغل ده بالطريقة اليدوي. regex بتعمله في سطر — بس المنطق اللي قدامك هو اللي بيحصل جوّه.

1line = "Room 12 has 3 patients and 2 nurses"◂
2numbers = []
3current = ""
4for ch in line:
5 if ch.isdigit():
6 current = current + ch
7 else:
8 if current != "":
9 numbers.append(int(current))
10 current = ""
11if current != "":
12 numbers.append(int(current))
13print(numbers)
14print("Sum:", sum(numbers))
الذاكرة
line'Room 12 has 3 patients and 2 nurses'
الناتج على الشاشة
لسه ما اتطبعش حاجة…
1

حطّينا 'Room 12 has 3 patients and 2 nurses' جوّه line

خطوة 1151 خطوة
Python الحقيقيCPython 3.14

المحاكاة فوق بتشرحلك خطوة خطوة. دوس هنا عشان تشغّل نفس code على Python حقيقي وتتأكد بنفسك.
أول مرة هيحمّل ~11 ميجا — بعد كده بيبقى فوري.

7

غلطات بتحصل كتير

شوفها هنا بدل ما تضيّع ساعة فيها

غلط
re.findall("\d+", text)
صح
re.findall(r"\d+", text)

من غير r Python بتفسّر \d كحرف خاص. دايمًا استخدم raw string.

غلط
nums = re.findall(r"\d+", line)
print(sum(nums))
صح
nums = re.findall(r"\d+", line)
print(sum(int(n) for n in nums))

findall بترجّع strings. لازم تحوّلهم لأرقام قبل الجمع.

غلط
if re.search(r"ok", line) == True:
صح
if re.search(r"ok", line):

search بترجّع object تطابق أو None — مش True/False.

8

مسائل سريعة

فكّر الأول — بعدين اكشف

1

إيه اللي النمط ده بيمسكه؟

1r"\d+"
2

وإيه الفرق لو شلنا الـ +؟

1r"\d"
3

ليه فيه باك سلاش قبل النقطة؟

1r"\d+\.\d+"
4

إيه اللي ده بيمسكه؟

1r"^OK"
5

re.findall بترجّع إيه؟

6

re.search بترجّع إيه لو ملقتش؟

7

ليه r قبل النمط؟

1r"\d+"
8

إمتى in أحسن من regex؟

9

جرّب بنفسك

اكتب code — ده الجزء اللي بيعلّم فعلاً

جرّب بنفسك

من غير regex: اكتب code يعدّ كام رقم في string "a1b22c333" (كل مجموعة أرقام متلاصقة = رقم واحد).

شغّل code خطوة خطوة
1text = "a1b22c333"◂
2count = 0
3# write here
4
الذاكرة
text'a1b22c333'
الناتج على الشاشة
لسه ما اتطبعش حاجة…
1

حطّينا 'a1b22c333' جوّه text

خطوة 13 خطوات
Python الحقيقيCPython 3.14

المحاكاة فوق بتشرحلك خطوة خطوة. دوس هنا عشان تشغّل نفس code على Python حقيقي وتتأكد بنفسك.
أول مرة هيحمّل ~11 ميجا — بعد كده بيبقى فوري.

تمرين إضافي 2
جرّب بنفسك

بالطريقة اليدوي (من غير regex): طلّع كل الأرقام من string "a12b3c45" واجمعها.

شغّل code خطوة خطوة
1text = "a12b3c45"◂
2numbers = []
3current = ""
4# write here
5
الذاكرة
text'a12b3c45'
الناتج على الشاشة
لسه ما اتطبعش حاجة…
1

حطّينا 'a12b3c45' جوّه text

خطوة 14 خطوات
Python الحقيقيCPython 3.14

المحاكاة فوق بتشرحلك خطوة خطوة. دوس هنا عشان تشغّل نفس code على Python حقيقي وتتأكد بنفسك.
أول مرة هيحمّل ~11 ميجا — بعد كده بيبقى فوري.

تمرين إضافي 3
جرّب بنفسك

بالطريقة اليدوي: اخفي كل رقم في string "تليفون 01012345678" بنجمة.

شغّل code خطوة خطوة
1text = "phone 01012345678"◂
2hidden = ""
3# write here
4
الذاكرة
text'phone 01012345678'
الناتج على الشاشة
لسه ما اتطبعش حاجة…
1

حطّينا 'phone 01012345678' جوّه text

خطوة 13 خطوات
Python الحقيقيCPython 3.14

المحاكاة فوق بتشرحلك خطوة خطوة. دوس هنا عشان تشغّل نفس code على Python حقيقي وتتأكد بنفسك.
أول مرة هيحمّل ~11 ميجا — بعد كده بيبقى فوري.

تمرين إضافي 4
جرّب بنفسك

بالطريقة اليدوي: اتأكد إن string "ali@borg.edu.eg" شكله إيميل — فيه @ واحدة بس، وفيه نقطة بعدها.

شغّل code خطوة خطوة
1email = "ali@borg.edu.eg"◂
2# write here
3
الذاكرة
email'ali@borg.edu.eg'
الناتج على الشاشة
لسه ما اتطبعش حاجة…
1

حطّينا 'ali@borg.edu.eg' جوّه email

خطوة 1خطوتين
Python الحقيقيCPython 3.14

المحاكاة فوق بتشرحلك خطوة خطوة. دوس هنا عشان تشغّل نفس code على Python حقيقي وتتأكد بنفسك.
أول مرة هيحمّل ~11 ميجا — بعد كده بيبقى فوري.

10

اختبر نفسك

كل إجابة معاها السبب

1

إيه الفرق بين r"\d" و r"\d+" ؟

2

ليه بنكتب \. في النمط r"\d+\.\d+" ؟

3

re.search بترجّع إيه لو ملقتش تطابق؟

4

إيه اللي \d+ بتمسكه؟

5

ليه بنحط r قبل النمط؟

6

re.findall(r"\d+", "a1b22") بترجّع إيه؟

7

إمتى الأفضل تستخدم in بدل regex؟

خلصت الدرس؟

علّم عليه عشان تعرف إنت وصلت لفين لما ترجع تاني.

الدرس اللي بعده: Objects و Classes ←