العمل مع السلاسل النصية
أهداف التعلّم
بعد إتمام هذا القسم
- ستتمكّن من استخدام المشغّلَين
+و*مع السلاسل النصية- ستعرف كيف تجد طول سلسلة نصية
- ستعرف ما المقصود بفهرسة السلاسل النصية
- ستعرف كيف تبحث عن السلاسل الفرعية داخل سلسلة نصية
عمليات السلاسل النصية
يمكن دمج السلاسل النصية، أو دمجها معًا (concatenating)، بواسطة المشغّل +:
begin = "ex"
end = "ample"
word = begin+end
print(word)
example
ويمكن أيضًا استخدام المشغّل * مع سلسلة نصية عندما يكون الطرف الآخر عددًا صحيحًا. عندئذٍ تُكرَّر السلسلة النصية بقدر المرات الذي يحدده ذلك العدد. فمثلًا، سيعمل هذا:
word = "banana"
print(word*3)
bananabananabanana
وباستخدام عمليات السلاسل النصية مع حلقة، يمكننا كتابة برنامج يرسم هرمًا:
n = 10 # number of layers in the pyramid
row = "*"
while n > 0:
print(" " * n + row)
row += "**"
n -= 1
يطبع هذا ما يلي:
*
***
*****
*******
*********
***********
*************
***************
*****************
*******************
يطبع الأمر print داخل الحلقة سطرًا يبدأ بـn محارف مسافة، ثم يليه ما هو مخزّن في المتغيّر row. ثم تُضاف نجمتان إلى نهاية المتغيّر row، وتُنقص قيمة المتغيّر n بمقدار 1.
تمرين تفاعلي: سلسلة نصية مضروبة
يُرجى كتابة برنامج يطلب من المستخدم سلسلة نصية ومقدارًا. ثم يطبع البرنامج السلسلة النصية بقدر المرات الذي يحدده المقدار. وينبغي أن يكون المخرَج كله في سطر واحد، دون إضافة أي مسافات أو رموز زائدة.
مثال على السلوك المتوقَّع:
Please type in a string: **hiya**
Please type in an amount: **4**
hiyahiyahiyahiya
ملاحظة: هذا التمرين يتطلب بيئة TMC التفاعلية ولا يعمل في النسخة الثابتة.
طول السلسلة النصية وفهرسها
تعيد الدالة len عدد المحارف في السلسلة النصية، وهو قيمة عدد صحيح دائمًا. فمثلًا، تعيد len("hey") العدد 3، لأن في السلسلة النصية hey ثلاثة محارف.
يطلب البرنامج التالي من المستخدم سلسلة نصية ثم يطبعها «مشطوبة». ويطبع البرنامج سطرًا ثانيًا بعدد من محارف - يساوي طول المُدخَل:
input_string = input("Please type in a string: ")
print(input_string)
print("-"*len(input_string))
Hi there!
---------
يشمل طول السلسلة النصية جميع المحارف الموجودة فيها، بما في ذلك محارف المسافات الفارغة. فمثلًا، طول السلسلة النصية bye bye هو 7.
تمرين تفاعلي: السلسلة النصية الأطول
يُرجى كتابة برنامج يطلب من المستخدم سلسلتين نصيتين ثم يطبع أيّهما أطول - أي التي تحتوي على محارف أكثر. وإذا كانت السلسلتان متساويتين في الطول، فينبغي للبرنامج أن يطبع "The strings are equally long".
بعض الأمثلة على السلوك المتوقَّع:
Please type in string 1: **hey**
Please type in string 2: **hiya**
hiya is longer
Please type in string 1: **howdy doody**
Please type in string 2: **hola**
howdy doody is longer
Please type in string 1: **hey**
Please type in string 2: **bye**
The strings are equally long
ملاحظة: هذا التمرين يتطلب بيئة TMC التفاعلية ولا يعمل في النسخة الثابتة.
ولأن السلاسل النصية هي في جوهرها تتابعات من المحارف، فبإمكانك أيضًا استرجاع أي محرف منفرد في السلسلة النصية. فالمشغّل [] يجد المحرف الذي له الـ_فهرس_ (index) المحدَّد بين الأقواس المربّعة.
يشير الفهرس إلى موضع في السلسلة النصية، ويُعدّ بدءًا من الصفر. فالمحرف الأول في السلسلة النصية فهرسه 0، والمحرف الثاني فهرسه 1، وهكذا.

فمثلًا، هذا البرنامج
input_string = input("Please type in a string: ")
print(input_string[0])
print(input_string[1])
print(input_string[3])
سيطبع ما يلي:
Please type in a string: **monkey**
m
o
k
ولأن المحرف الأول في السلسلة النصية فهرسه 0، فإن المحرف الأخير فهرسه الطول - 1. ويطبع البرنامج التالي المحرفَ الأول والمحرفَ الأخير لسلسلة نصية:
input_string = input("Please type in a string: ")
print("First character: " + input_string[0])
print("Last character: " + input_string[len(input_string) - 1])
Please type in a string: **testing**
First character: t
Last character: g
يدور البرنامج التالي على جميع محارف السلسلة النصية من الأول إلى الأخير:
input_string = input("Please type in a string: ")
index = 0
while index < len(input_string):
print(input_string[index])
index += 1
Please type in a string: **test**
t
e
s
t
ويمكنك أيضًا استخدام الفهرسة السالبة للوصول إلى المحارف بدءًا من نهاية السلسلة النصية. فالمحرف الأخير في السلسلة النصية فهرسه -1، والمحرف الذي يسب الأخير فهرسه -2، وهكذا. ويمكنك أن تنظر إلى input_string[-1] على أنها صيغة مختصرة لـ input_string[len(input_string) - 1].

ويمكن تبسيط المثال السابق باستخدام الفهرسة السالبة:
input_string = input("Please type in a string: ")
print("First character: " + input_string[0])
print("Last character: " + input_string[-1])
Please type in a string: **testing**
First character: t
Last character: g
IndexError: فهرس السلسلة النصية خارج النطاق
إذا جرّبت الأمثلة أعلاه بنفسك، فقد تكون صادفت رسالة الخطأ IndexError: string index out of range. ويظهر هذا الخطأ إذا حاولت الوصول إلى فهرس غير موجود في السلسلة النصية.
input_string = input("Please type in a string: ")
print("The tenth character: " + input_string[9])
Please type in a string: **introduction to programming**
The tenth character: i
Please type in a string: **python**
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: string index out of range
أحيانًا يكون خطأ الفهرسة ناتجًا عن خلل في الشيفرة. فمثلًا، من الشائع جدًا أن تُفرط في الفهرسة عند محاولة الوصول إلى المحرف الأخير في سلسلة نصية:
input_string = input("Please type in a string: ")
print("Last character: " + input_string[len(input_string)])
ولأن فهرسة السلاسل النصية تبدأ من الصفر، فإن المحرف الأخير فهرسه len(input_string) - 1 وليس len(input_string).
وهناك حالات ينبغي فيها للبرنامج أن يستعدّ للأخطاء الناتجة عن مُدخَل المستخدم:
input_string = input("Please type in a string: ")
if len(input_string) > 0:
print("First character: " + input_string[0])
else:
print("The input string is empty. There is no first character.")
في المثال أعلاه، لو لم يكن المبرمج قد أدرج فحصًا لطول سلسلة المُدخَل النصية، لأسفرت سلسلة نصية طولها صفر عن خطأ. وتُسمّى السلسلة النصية التي طولها صفر أيضًا السلسلة النصية الفارغة (empty string)، ويمكن الحصول عليها هنا بالضغط على Enter عند مُوجّه الإدخال.
تمرين تفاعلي: من النهاية إلى البداية
يُرجى كتابة برنامج يطلب من المستخدم سلسلة نصية. ثم يطبع البرنامج سلسلة المُدخَل بالترتيب المعكوس، من النهاية إلى البداية. وينبغي أن يكون كل محرف في سطر منفصل.
مثال على السلوك المتوقَّع:
Please type in a string: **hiya**
a
y
i
h
ملاحظة: هذا التمرين يتطلب بيئة TMC التفاعلية ولا يعمل في النسخة الثابتة.
تمرين تفاعلي: المحرف الثاني والمحرف الذي يسب الأخير
يُرجى كتابة برنامج يطلب من المستخدم سلسلة نصية. ثم يطبع البرنامج رسالة بناءً على ما إذا كان المحرف الثاني والمحرف الذي يسب الأخير متطابقين أم لا. انظر الأمثلة أدناه.
Please type in a string: **python**
The second and the second to last characters are different
Please type in a string: **pascal**
The second and the second to last characters are a
ملاحظة: هذا التمرين يتطلب بيئة TMC التفاعلية ولا يعمل في النسخة الثابتة.
تمرين تفاعلي: سطر من محارف
#يُرجى كتابة برنامج يطبع سطرًا من محارف
#يختار المستخدم عرضه.
###
########
ملاحظة: هذا التمرين يتطلب بيئة TMC التفاعلية ولا يعمل في النسخة الثابتة.
تمرين تفاعلي: مستطيل من محارف
#يُرجى تعديل البرنامج السابق بحيث يطلب الارتفاع أيضًا، ويطبع مستطيلًا من محارف
#بناءً على ذلك.
Width: **10**
Height: **3**
##########
##########
##########
ملاحظة: هذا التمرين يتطلب بيئة TMC التفاعلية ولا يعمل في النسخة الثابتة.
تمرين تفاعلي: التشطيب
يُرجى كتابة برنامج يطلب من المستخدم سلاسل نصية باستخدام حلقة. ويطبع البرنامج كل سلسلة نصية مشطوبة كما هو مبيّن في الأمثلة أدناه. وينتهي التنفيذ حين يدخل المستخدم سلسلة نصية فارغة - أي حين يضغط Enter عند المُوجّه فقط.
Hi there!
---------
ملاحظة: هذا التمرين يتطلب بيئة TMC التفاعلية ولا يعمل في النسخة الثابتة.
تمرين تفاعلي: محاذاة إلى اليمين
يُرجى كتابة برنامج يطلب من المستخدم سلسلة نصية ثم يطبعها بحيث يُعرَض بالضبط 20 محرفًا. فإذا كان المُدخَل أقصر من 20 محرفًا، فإن بداية السطر تُملأ بمحارف
*.
يمكنك افتراض أن سلسلة المُدخَل النصية طولها 20 محرفًا على الأكثر.
**************python
*******alongerstring
*averyverylongstring
ملاحظة: هذا التمرين يتطلب بيئة TMC التفاعلية ولا يعمل في النسخة الثابتة.
تمرين تفاعلي: كلمة داخل إطار
يُرجى كتابة برنامج يطلب من المستخدم سلسلة نصية ثم يطبع إطارًا من محارف
*تتوسّطه الكلمة. وينبغي أن يكون عرض الإطار 30 محرفًا. ويمكنك افتراض أن سلسلة المُدخَل النصية ستأخذ مكانها دائمًا داخل الإطار.
وإذا كان طول سلسلة المُدخَل النصية عددًا فرديًا، فيجوز لك أن تطبع الكلمة في أيٍّ من موضعي المنتصف الممكنين.
******************************
* testing *
******************************
******************************
* python *
******************************
ملاحظة: هذا التمرين يتطلب بيئة TMC التفاعلية ولا يعمل في النسخة الثابتة.
السلاسل الفرعية والشرائح
السلسلة الفرعية (substring) من سلسلة نصية هي تتابع من المحارف يشكّل جزءًا من تلك السلسلة النصية. فمثلًا، تحتوي السلسلة النصية example على السلاسل الفرعية exam وamp وple وغيرها. وفي برمجة Python، تُسمّى عملية اختيار السلاسل الفرعية عادةً التقطيع (slicing)، وكثيرًا ما تُشار إلى السلسلة الفرعية بأنها شريحة (slice) من السلسلة النصية. ويمكن استخدام المصطلحين في أغلب الأحيان بشكل متبادل.
إذا كنت تعرف فهرسي بداية الشريحة ونهايتها التي تريد استخراجها، فيمكنك فعل ذلك باستخدام الترميز [a:b]. وهذا يعني أن الشريحة تبدأ عند الفهرس a وتنتهي عند آخر محرف قبل الفهرس b - أي أنها تضم الأول وتستثني الأخير. ويمكنك أن تتخيّل الفهارس كخطوط فاصلة مرسومة على الجانب الأيسر من المحرف المُفهرَس، كما هو موضَّح في الصورة أدناه:

فلننظر عن قرب إلى بعض السلاسل النصية المقطَّعة:
input_string = "presumptious"
print(input_string[0:3])
print(input_string[4:10])
# if the beginning index is left out, it defaults to 0
print(input_string[:3])
# if the end index is left out, it defaults to the length of the string
print(input_string[4:])
pre
umptio
pre
umptious
الفترات نصف المفتوحة
في معالجة السلاسل النصية في Python، الفترة
[a:b]نصف مفتوحة (half open)، وهذا يعني في هذه الحالة أن المحرف عند فهرس البدايةaمُضمَّن في الفترة، بينما المحرف عند فهرس النهايةbمُستثنى منها. ولماذا ذلك؟لا يوجد سبب عميق لهذه الميزة. إنها بالأحرى عُرف متوارث من لغات برمجة أخرى.
قد تبدو الفترات نصف المفتوحة غير بديهية، لكنها في الواقع تتمتّع ببعض المزايا. فمثلًا، يمكنك بسهولة حساب طول الشريحة بـ
b-a. ومن الجهة الأخرى، عليك دائمًا أن تتذكّر أن المحرف عند فهرس النهايةbلن يكون مُضمَّنًا في الشريحة.
تمرين تفاعلي: السلاسل الفرعية، الجزء 1
يُرجى كتابة برنامج يطلب من المستخدم إدخال سلسلة نصية. ثم يطبع البرنامج جميع السلاسل الفرعية التي تبدأ بالمحرف الأول، من الأقصر إلى الأطول. انظر المثال أدناه.
Please type in a string: **test**
t
te
tes
test
ملاحظة: هذا التمرين يتطلب بيئة TMC التفاعلية ولا يعمل في النسخة الثابتة.
تمرين تفاعلي: السلاسل الفرعية، الجزء 2
يُرجى كتابة برنامج يطلب من المستخدم إدخال سلسلة نصية. ثم يطبع البرنامج جميع السلاسل الفرعية التي تنتهي بالمحرف الأخير، من الأقصر إلى الأطول. انظر المثال أدناه.
Please type in a string: **test**
t
st
est
test
ملاحظة: هذا التمرين يتطلب بيئة TMC التفاعلية ولا يعمل في النسخة الثابتة.
البحث عن السلاسل الفرعية
يمكن للمشغّل in أن يخبرنا ما إذا كانت سلسلة نصية تحتوي على سلسلة فرعية معيّنة. فالتعبير المنطقي a in b يكون صحيحًا إذا كانت b تحتوي على السلسلة الفرعية a.
فمثلًا، فإن هذه القطعة من الشيفرة
input_string = "test"
print("t" in input_string)
print("x" in input_string)
print("es" in input_string)
print("ets" in input_string)
تطبع ما يلي:
True
False
True
False
يتيح البرنامج التالي للمستخدم البحث عن سلاسل فرعية داخل سلسلة نصية مُرمَّزة ثابتًا في البرنامج:
input_string = "perpendicular"
while True:
substring = input("What are you looking for? ")
if substring in input_string:
print("Found it")
else:
print("Not found")
What are you looking for? **perp**
Found it
What are you looking for? **abc**
Not found
What are you looking for? **pen**
Found it
...
تمرين تفاعلي: هل تحتوي على حروف العلة
يُرجى كتابة برنامج يطلب من المستخدم إدخال سلسلة نصية. ثم يطبع البرنامج رسائل مختلفة إذا كانت السلسلة النصية تحتوي على أيٍّ من حروف العلة a أو e أو o.
يمكنك افتراض أن المُدخَل سيكون بأحرف صغيرة بالكامل. انظر الأمثلة أدناه.
Please type in a string: **hello there**
a not found
e found
o found
Please type in a string: **hiya**
a found
e not found
o not found
ملاحظة: هذا التمرين يتطلب بيئة TMC التفاعلية ولا يعمل في النسخة الثابتة.
يعيد المشغّل in قيمة منطقية، لذا فإنه لا يخبرنا سوى بما إذا كانت هناك سلسلة فرعية داخل سلسلة نصية، لكنه لا يكون مفيدًا في تحديد مكانها بالضبط. وبدلًا من ذلك، يمكن استخدام تابع السلاسل النصية find في Python لهذا الغرض. وهو يأخذ السلسلة الفرعية المُبحَث عنها وسيطًا، ويعيد إمّا أول فهرس وُجدت عنده أو -1 إذا لم تُعثر على السلسلة الفرعية داخل السلسلة النصية.
توضّح الصورة التالية كيف يُستخدم:

بعض أمثلة استخدام find:
input_string = "test"
print(input_string.find("t"))
print(input_string.find("x"))
print(input_string.find("es"))
print(input_string.find("ets"))
0
-1
1
-1
مثال البحث عن السلاسل الفرعية أعلاه مُنفَّذًا باستخدام find:
input_string = "perpendicular"
while True:
substring = input("What are you looking for? ")
index = input_string.find(substring)
if index >= 0:
print(f"Found it at the index {index}")
else:
print("Not found")
What are you looking for? **perp**
Found it at the index 0
What are you looking for? **abc**
Not found
What are you looking for? **pen**
Found it at the index 3
...
التوابع
استخدمنا أعلاه تابع السلسلة النصية
find. وتعمل التوابع بطريقة مشابهة إلى حدٍّ كبير للدوال (functions) التي تناولناها في الجزء السابق. وما يميّزها عن الدوال أن التوابع مرتبطة دائمًا بـ_الكائن_ الذي تُستدعى عليه. والكائن هو الشيء المُسمّى قبل اسم التابع في استدعاءه. وفي حالةfindيكون الكائن هو السلسلة النصية التي يبحث فيها التابع عن السلسلة الفرعية المُمرَّرة إليه كوسيط.
تمرين تفاعلي: أوجد السلسلة الفرعية الأولى
يُرجى كتابة برنامج يطلب من المستخدم إدخال سلسلة نصية ومحرف واحد. ثم يطبع البرنامج شريحة المحارف الثلاثة الأولى التي تبدأ بالمحرف الذي يحدده المستخدم. ويمكنك افتراض أن سلسلة المُدخَل النصية طولها ثلاثة محارف على الأقل. ويجب أن يطبع البرنامج ثلاثة محارف، أو لا يطبع شيئًا على الإطلاق.
انتبه بصفة خاصة إلى الحالة التي يتبقّى فيها أقل من محرفين في السلسلة النصية بعد أول ظهور للمحرف المُبحَث عنه. في هذه الحالة لا ينبغي طباعة شيء، ولا ينبغي أن تحدث أي أخطاء في الفهرسة أثناء تنفيذ البرنامج.
Please type in a word: **mammoth**
Please type in a character: **m**
mam
Please type in a word: **banana**
Please type in a character: **n**
nan
Please type in a word: **tomato**
Please type in a character: **x**
Please type in a word: **python**
Please type in a character: **n**
ملاحظة: هذا التمرين يتطلب بيئة TMC التفاعلية ولا يعمل في النسخة الثابتة.
تمرين تفاعلي: أوجد جميع السلاسل الفرعية
يُرجى إنشاء نسخة موسَّعة من البرنامج السابق، تطبع جميع السلاسل الفرعية التي يبلغ طولها ثلاثة محارف على الأقل والتي تبدأ بالمحرف الذي يحدده المستخدم. ويمكنك افتراض أن سلسلة المُدخَل النصية طولها ثلاثة محارف على الأقل.
Please type in a word: **mammoth**
Please type in a character: **m**
mam
mmo
mot
Please type in a word: **banana**
Please type in a character: **n**
nan
تلميح قد يمنحك المثال التالي بعض الإلهام حول كيفية معالجة هذا التمرين:
word = input("Word: ")
while True:
if len(word) == 0:
break
print(word)
word = word[2:]
Word: **mammoth**
mammoth
mmoth
oth
h
ملاحظة: هذا التمرين يتطلب بيئة TMC التفاعلية ولا يعمل في النسخة الثابتة.
تمرين تفاعلي: الظهور الثاني
يُرجى كتابة برنامج يجد الظهور الثاني لسلسلة فرعية. وإذا لم يكن هناك ظهور ثانٍ (أو أول)، فينبغي للبرنامج أن يطبع رسالة تصف ذلك.
في هذا التمرين لا يمكن أن يتداخل الظهوران. فمثلًا، في السلسلة النصية aaaa يقع الظهور الثاني للسلسلة الفرعية aa عند الفهرس 2.
بعض الأمثلة على السلوك المتوقَّع:
Please type in a string: **abcabc**
Please type in a substring: **ab**
The second occurrence of the substring is at index 3.
Please type in a string: **methodology**
Please type in a substring: **o**
The second occurrence of the substring is at index 6.
Please type in a string: **aybabtu**
Please type in a substring: **ba**
The substring does not occur twice in the string.
ملاحظة: هذا التمرين يتطلب بيئة TMC التفاعلية ولا يعمل في النسخة الثابتة.