التعامل مع النصوص — الفهرسة، التقطيع، ونصوص التنسيق (f-strings)
استخراج أجزاء من النصوص، وتنظيفها، وتعديلها، وبناء رسائل واضحة باستخدام f-strings — مع قاعدة أن النصوص غير قابلة للتعديل المباشر في مكانها.
كيف تريد أن تتعلم؟
المشكلة التي نقوم بحلها
وصل اسم من نموذج إدخال: " Rafi Ahmed ". في بدايته ونهايته مسافات زائدة، وأنت تحتاج إلى الاسم الأول فقط، وإلى رسالة — "Welcome, Rafi!".
هذا العمل — تنظيف السلسلة النصية (string)، واستخراج أجزاء منها، وبناء رسالة جديدة بها — من أكثر المهام تكراراً في البرمجة. أسماء المستخدمين، والبريد الإلكتروني، والمعرّفات، وأسماء الملفات، والعناوين، والردود القادمة من واجهة API — كلها سلاسل نصية.
وسيتضح اليوم أمر آخر يضيّع ساعات على من لا يعرفه: في بايثون لا يمكن تعديل السلسلة النصية. كتابة name.upper() لا تجعل name بأحرف كبيرة. لماذا لا يحدث ذلك، وماذا نفعل بدلاً منه — هذا أثمن جزء في هذا الفصل.
في نهاية هذا الفصل ستكون قادراً على
- الوصول إلى أي حرف في السلسلة النصية باستخدام الفهرس (index)، من الأمام ومن الخلف
- قصّ جزء منها باستخدام الشريحة (slice)
- تنظيف السلاسل النصية وتغييرها باستخدام
stripوupperوlowerوreplaceوsplit - فهم لماذا يجب الاحتفاظ بنتيجة الطريقة (method)
- بناء رسائل سهلة القراءة باستخدام f-string
المتطلبات السابقة: العمليات الحسابية — القسمة، البواقي، وفخ الأعداد العشرية.
علامات الاقتباس — مفردة أم مزدوجة
بالنسبة لبايثون، 'Rafi' و "Rafi" شيء واحد. يوجد النوعان حتى لا تسبب علامات الاقتباس داخل السلسلة النصية أي مشكلة:
print("It's working")
print('She said "yes"')It's working
She said "yes"ثلاث علامات اقتباس تسمح بكتابة سلسلة نصية من عدة أسطر:
note = """Dear customer,
Your order is confirmed.
Thank you."""
print(note)Dear customer,
Your order is confirmed.
Thank you.وكتابة \n تنشئ سطراً جديداً، و \t تنشئ مسافة جدولة (tab):
print("Name:\tRafi\nRole:\tLearner")Name: Rafi
Role: Learnerالطول والفهرس
word = "PYTHON"
print(len(word))
print(word[0])
print(word[1])
print(word[-1])
print(word[-2])6
P
Y
N
Oأمران يجب أن يرسخا في ذهنك:
العدّ يبدأ من الصفر. فهرس الحرف الأول 0، والثاني 1. لذلك في كلمة من ستة أحرف يكون فهرس الحرف الأخير 5 وليس 6. إذا كتبت word[6] فسيظهر الخطأ IndexError. هذا الخطأ "بواحد زائد" شائع لدرجة أن له اسماً خاصاً بالإنجليزية — off-by-one error.
الفهرس السالب يعدّ من الخلف. word[-1] هو الحرف الأخير، و word[-2] الذي قبله. هذه هي الطريقة السهلة للوصول إلى الحرف الأخير دون معرفة طول الكلمة.
الشريحة — قصّ جزء من السلسلة
word = "PROGRAMMING"
print(word[0:7])
print(word[7:11])
print(word[:7])
print(word[7:])
print(word[-4:])PROGRAM
MING
PROGRAM
MING
MINGword[a:b] تعني من a حتى ما قبل b. الرقم الأخير لا يدخل في النتيجة.
يبدو هذا غريباً في البداية، لكن له فائدة: word[0:7] و word[7:11] — الجزءان يلتحمان تماماً، فلا يتكرر حرف ولا يسقط حرف. إذا حذفت الرقم الأول فالمعنى "من البداية تماماً"، وإذا حذفت الرقم الأخير فالمعنى "حتى النهاية تماماً".
لا يمكن تعديل السلسلة النصية
هذه أهم قاعدة في هذا الفصل:
name = "rafi"
name[0] = "R"Traceback (most recent call last):
File "D:\python-lab\lesson-06\demo.py", line 2, in <module>
name[0] = "R"
~~~~^^^
TypeError: 'str' object does not support item assignmentسطر File الأول يحتوي على المسار الكامل لملفك، لذلك سيبدو مختلفاً على حاسوبك. المعنى الحقيقي في السطر الأخير: لا يمكن تغيير حرف داخل سلسلة نصية بعد إنشائها. إذن كيف يتم تحويل الأحرف إلى كبيرة، أو قصّ المسافات؟ الجواب: بايثون لا يغيّر السلسلة القديمة، بل ينشئ سلسلة جديدة ويعيدها.
name = " rafi "
print(name.strip())
print(name.strip().upper())
print("After all that, name is still:", name)rafi
RAFI
After all that, name is still: rafiلم يتغير name إطلاقاً. أنشأت strip() سلسلة جديدة نظيفة، ونحن طبعناها فقط — ولم نحفظها في أي مكان.
لذلك يجب الاحتفاظ بالنتيجة:
name = " rafi "
clean_name = name.strip().upper()
print(clean_name)RAFIأو أعد إسنادها إلى الاسم نفسه — name = name.strip(). استدعاء الطريقة دون الاحتفاظ بنتيجتها خطأ يقع فيه الجميع في البداية. ولا يظهر أي خطأ، لذلك يستغرق اكتشافه وقتاً.
طرق مفيدة
raw = " Rafi Ahmed "
print(raw.strip())
print(raw.strip().lower())
print(raw.strip().upper())
print(raw.strip().replace(" ", "_"))
print(len(raw), len(raw.strip()))
print("rafi" in raw.lower())Rafi Ahmed
rafi ahmed
RAFI AHMED
Rafi_Ahmed
14 10
Truestrip()— تقصّ المسافات الفارغة في البداية والنهاية (وليس في الوسط)lower()/upper()— تحوّل إلى أحرف صغيرة أو كبيرةreplace(a, b)— تضعbمكان كلain— تخبرك هل توجد سلسلة نصية داخل أخرى أم لا
و split() تقسّم السلسلة النصية إلى أجزاء:
full_name = "Rafi Ahmed Khan"
parts = full_name.split(" ")
print(parts)
print(parts[0])
print(len(parts))['Rafi', 'Ahmed', 'Khan']
Rafi
3الشيء الموجود بين الأقواس المربعة يسمّى القائمة (list) — ولها فصل خاص لاحقاً. يكفي الآن أن تعرف أن split() تعيد الأجزاء بهذا الشكل، وأنه يمكن أخذ جزء واحد باستخدام الفهرس.
نظّف قبل أن تقارن. إذا كتب المستخدم"Rafi "فهي لا تساوي"rafi"— مسافة زائدة في النهاية وحرف كبير، أي فرقان. لهذا فإن تشغيل.strip().lower()قبل المقارنة قاعدة في معظم المشاريع تقريباً.
f-string — الطريقة السهلة لبناء رسالة
كان دمج النصوص مع الأرقام مزعجاً حتى الآن. تجعل f-string ذلك سهلاً — حرف f قبل علامة الاقتباس، وفي الداخل ما تشاء بين قوسين معقوصين {}:
name = "Rafi"
items = 3
price = 12.5
print(f"Hello, {name}!")
print(f"{items} items cost {items * price}")
print(f"Rounded: {items * price:.2f}")Hello, Rafi!
3 items cost 37.5
Rounded: 37.50لاحظ ثلاث فوائد: يمكن إجراء الحساب مباشرة في الداخل (items * price)، ولا حاجة للتفكير في النوع (يتحول الرقم إلى نص تلقائياً)، و :.2f تحدد عدد الخانات بعد الفاصلة العشرية — وهو ما نحتاجه في كل مرة نعرض فيها مبلغاً مالياً.
انظر مرة واحدة إلى ما يحدث عند نسيان f:
name = "Rafi"
print("Hello, {name}")Hello, {name}لا يوجد خطأ، فقط الرسالة خاطئة. رؤيتها مرة واحدة تسهّل اكتشافها لاحقاً.
مثال كامل
account.py:
# Turn a raw form entry into a clean display name and a login id
raw_input_name = " Rafi Ahmed "
domain = "example.com"
clean = raw_input_name.strip()
parts = clean.split(" ")
first_name = parts[0]
last_name = parts[-1]
login_id = f"{first_name.lower()}.{last_name.lower()}"
email = f"{login_id}@{domain}"
initials = f"{first_name[0]}{last_name[0]}"
print(f"Display name : {clean}")
print(f"Login id : {login_id}")
print(f"Email : {email}")
print(f"Initials : {initials}")
print(f"Name length : {len(clean)} characters")Display name : Rafi Ahmed
Login id : rafi.ahmed
Email : [email protected]
Initials : RA
Name length : 10 charactersلماذا parts[-1]؟ لأن اسم الشخص قد يتكون من ثلاثة أجزاء. أخذ الجزء الأخير من الخلف يعمل سواء كان الاسم من جزأين أو من ثلاثة.
حالات الخطأ الشائعة وحلولها
IndexError: string index out of range الفهرس الذي طلبته خارج طول السلسلة النصية. تذكّر: إذا كان len(word) يساوي 6، فالفهارس الصحيحة من 0 إلى 5. للحرف الأخير، word[-1] هو الأكثر أماناً.
TypeError: 'str' object does not support item assignment حاولت تغيير حرف داخل سلسلة نصية. هذا غير ممكن — يجب بناء سلسلة جديدة، مثل word = "R" + word[1:].
استدعيت الطريقة لكن لم يتغير شيء لم تُحفظ النتيجة في أي مكان. name.strip() لا تغيّر name نفسها؛ يجب أن تكتب name = name.strip().
strip() لا تحذف المسافات التي في الوسط عمل strip() على الطرفين فقط. لحذف المسافات الداخلية استخدم replace(" ", "").
الرسالة في f-string تظهر بشكل خاطئ تأكد من وجود f قبل علامة الاقتباس مباشرة. بدون f تُطبع الأقواس المعقوصة كأحرف عادية.
NameError — الاسم داخل f-string غير معروف الاسم الذي كتبته داخل القوسين المعقوصين لم يُنشأ من قبل، أو فيه خطأ إملائي.
الخطوة ٤ من ٦ — التوقع
تحقّق من فهمك
ما ناتج هذه الأسطر الأربعة؟
word = "PYTHON"
print(word[0])
print(word[-1])
print(word[1:4])- AP N YTH
- BY N YTHO
- CP O YTH
- DP N YTHO
كان المقصود طباعة Hello, RAFI!، لكن الاسم يظهر بأحرف صغيرة ومع المسافات الزائدة. لماذا؟
name = " rafi "
name.strip()
name.upper()
print(f"Hello, {name}!")- Aلا يمكن استدعاء طريقة على سلسلة نصية إلا مرة واحدة، لا مرتين
- Bلا يمكن لـ f-string أن تعرض نتيجة طريقة
- C`strip()` و `upper()` لا تغيّران السلسلة الأصلية، بل تعيدان سلسلة جديدة — يجب إسناد النتيجة إلى `name`
- Dلا يمكن استدعاء `strip()` قبل `upper()`؛ يجب عكس الترتيب
ماذا ستطبع هذه الـ f-string؟
item = "pen"
qty = 3
price = 12.5
print(f"{qty} x {item} = {qty * price:.2f}")- A3 x pen = 37.50
- B3 x pen = 37.5
- C{qty} x {item} = {qty * price}
- D3 x pen = 3 * 12.5
الإجابة تتطلب حساباً
سجّل الدخول للتحقق من إجاباتك
الأسئلة موجودة أعلاه، والتفكير في إجاباتها ذهنياً هو الجزء المهم. سجّل الدخول لرؤية الإجابات والتفسيرات والتلميحات ذات المستويات الثلاثة.
دورك الآن
اكتب ملفاً باسم slug.py يحوّل عنواناً إلى صيغة مناسبة للاستخدام في عنوان صفحة ويب.
القيمة الابتدائية: title = " Learn Python Step By Step "
يجب أن يكون الناتج:
Title : Learn Python Step By Step
Slug : learn-python-step-by-step
Slug length: 25أربعة شروط:
- قصّ المسافات الزائدة من الطرفين
- تحويل كل الأحرف إلى أحرف صغيرة
- وضع شرطة مكان المسافات الداخلية
- طباعة الأسطر الثلاثة كلها باستخدام f-string
ثم قم بأمر إضافي: غيّر قيمة title إلى " Python for Beginners " وشغّل البرنامج. إذا ظهرت النتيجة الصحيحة للعنوان الجديد دون أن تغيّر الكود، فهذا يعني أنك كتبت حساباً حقيقياً بدلاً من كتابة الأرقام بيدك.
في هذه المهمة المزيد
ما قرأته أعلاه هو المهمة كاملة — لم يُحذف منها شيء. يضيف Pro:
- ما يحدث فعلياً في الكواليس — كيف ينفذ بايثون هذا الكود
- الحل الكامل للتمرين مشروحاً خطوة بخطوة
- تمارين إضافية أكثر صعوبة وتحدياً
- أسئلة المقابلات الوظيفية حول هذا الموضوع مع نموذج الإجابة
الخطوة ٦ من ٦
التحدي — اختبار الفصل
عشرة أسئلة متدرجة من السهل إلى الصعب. الأسئلة الأخيرة صعبة عن قصد.
سجّل الدخول لأداء الاختبار