השוואת מחרוזות באמצעות Python

ב-Python, מחרוזות הן רצפים של תווים, המאוחסנים למעשה בזיכרון כאובייקט. ניתן לזהות כל אובייקט באמצעות ה id() שיטה, כפי שניתן לראות להלן. Python מנסה לעשות שימוש חוזר באובייקטים בזיכרון בעלי אותו ערך, מה שגם הופך את השוואת אובייקטים למהירה מאוד ב-Python:

$ python
Python 3.9.0 (v3.9.0:9cf6752276, Oct  5 2020, 11:29:23) 
[Clang 6.0 (clang-600.0.57)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> a = "abc"
>>> b = "abc"
>>> c = "def"
>>> print (id(a), id(b), id(c))
(139949123041320, 139949123041320, 139949122390576)
>>> quit()

על מנת להשוות מחרוזות, Python מציעה כמה אופרטורים שונים לעשות זאת. ראשית, נסביר אותם בפירוט רב יותר להלן. שנית, נעבור על שניהם string ו re מודולים, המכילים שיטות לטיפול בהתאמות לא-רגישות רישיות ולא מדויקות. שלישית, כדי להתמודד עם מחרוזות מרובות שורות מודול difflib הוא די שימושי. מספר דוגמאות יעזרו לך להבין כיצד להשתמש בהן.

השווה בין Strngs עם האופרטורים == ו-!=

בתור אופרטור השוואה בסיסי תרצה להשתמש == ו !=. הם פועלים בדיוק באותו אופן כמו עם ערכי מספר שלם וצוף. ה == מפעיל חוזר True אם יש התאמה מדויקת, אחרת False יוחזר. לעומת זאת, ה != מפעיל חוזר True אם אין התאמה ובאופן אחר חוזר False. רישום 1 מדגים זאת.

ב for לולאה, מחרוזת המכילה את שם העיר השוויצרית "לוזאן" מושווה לערך מרשימה של מקומות אחרים, ותוצאת ההשוואה מודפסת על stdout.

רישום 1:


listOfPlaces = ["Berlin", "Paris", "Lausanne"]
currentCity = "Lausanne"

for place in listOfPlaces:
    print (f"comparing {place} with {currentCity}: %{place == currentCity}")

הפעלת הסקריפט של Python מלמעלה מהפלט היא כדלקמן:

$ python3 comparing-strings.py
comparing Berlin with Lausanne: False
comparing Paris with Lausanne: False
comparing Lausanne with Lausanne: True

השמיים == ו is מפעילים

לפייתון יש את שני אופרטורי ההשוואה == ו is. במבט ראשון נראה שהם זהים, אבל למעשה הם לא.

== משווה שני משתנים על סמך הערך שהם מייצגים. לעומת זאת, ה is אופרטור משווה שני משתנים על סמך מזהה האובייקט בזיכרון.

ג'ון (איילה) וג'ון (מו) נקראים שניהם ג'ון. אם נוכל לצמצם אותם רק לשמות שלהם, הם יהיו שווים בערכם, אבל עדיין שני אנשים שונים מבחינה איכותית.

הדוגמה הבאה מדגימה את זה עבור שלושה משתנים עם ערכי מחרוזת. שני המשתנים a ו b בעלי אותו ערך, ו-Python מתייחס לאותו אובייקט על מנת למזער את השימוש בזיכרון.

זה נעשה עבור סוגים ומחרוזות פשוטים כברירת מחדל, אך לא עבור אובייקטים אחרים:

>>> a = 'hello'
>>> b = 'hello'
>>> c = 'world'
>>> a is b
True
>>> a is c
False
>>> id(a)
140666888153840
>>> id(b)
140666888153840
>>> 

ברגע שהערך ישתנה Python תבצע מחדש את האובייקט ויקצה את המשתנה. בקטע הקוד הבא b מקבל את הערך של 2, ובהמשך b ו c מתייחסים לאותו אובייקט:

>>> b = 'world'
>>> id(b)
140666888154416
>>> id(c)
140666888154416

עוד מפעילי השוואה

להשוואה לגבי סדר לקסיקוגרפי ניתן להשתמש באופרטורי ההשוואה <, >, <=, ו >=. ההשוואה עצמה נעשית דמות אחר דמות. הסדר תלוי בסדר התווים באלפבית. סדר זה תלוי בטבלת התווים שנמצאת בשימוש במחשב שלך בזמן ביצוע קוד Python.

זכור שההזמנה תלויה רישיות. כדוגמה לאלפבית הלטיני, "אוטובוס" בא לפני "אוטובוס". רישום 2 מראה כיצד מפעילי ההשוואה הללו פועלים בפועל.

רישום 2:


listOfPlaces = ["Berlin", "Paris", "Lausanne"]
currentCity = "Lausanne"

for place in listOfPlaces:
    if place < currentCity:
            print (f"{place} comes before {currentCity}")
    elif place > currentCity:
            print (f"{place} comes after {currentCity}")
    else:
            print (f"{place} is equal to {currentCity}")

הפעלת הסקריפט של Python מלמעלה מהפלט היא כדלקמן:

$ python3 comparing-strings-order.py
Berlin comes before Lausanne
Paris comes after Lausanne
Lausanne is equal to Lausanne

השוואות מחרוזות חסרות רישיות

הדוגמאות הקודמות התמקדו בהתאמות מדויקות בין מחרוזות. כדי לאפשר השוואות חסרות רישיות Python מציעה שיטות מחרוזות מיוחדות כגון upper() ו lower(). שניהם זמינים ישירות כשיטות של אובייקט המחרוזת המתאים.

upper() ממיר את המחרוזת כולה לאותיות גדולות, ו lower() באותיות קטנות, בהתאמה. מבוסס על רישום 1 הרשימה הבאה מראה כיצד להשתמש ב- lower() שִׁיטָה.

עיין במדריך המעשי והמעשי שלנו ללימוד Git, עם שיטות עבודה מומלצות, סטנדרטים מקובלים בתעשייה ודף רמאות כלול. תפסיק לגוגל פקודות Git ולמעשה ללמוד זה!

רישום 3:


listOfPlaces = ["Berlin", "Paris", "Lausanne"]
currentCity = "lausANne"

for place in listOfPlaces:
    print (f"comparing {place} with {place.lower() == currentCity.lower()}: {currentCity}")

הפלט הוא כדלקמן:

$ python3 comparing-strings-case-insensitive.py
comparing Berlin with lausANne: False
comparing Paris with lausANne: False
comparing Lausanne with lausANne: True

השווה מחרוזות באמצעות ביטויים רגולריים (RegEx)

A ביטוי רגיל - או בקיצור "רגקס" - מגדיר דפוס ספציפי של תווים.

כדי לעשות שימוש במנגנון זה ב- Python, ייבא את re מודול ראשית ולהגדיר דפוס מסוים, לאחר מכן. שוב, הדוגמה הבאה מבוססת על רישום 1. תבנית החיפוש תואמת ל-"bay", ומתחילה באות קטנה או גדולה. בדיוק, הקוד הבא של Python מוצא את כל המחרוזות שבהן תבנית החיפוש מתרחשת, לא משנה באיזה מיקום של המחרוזת - בהתחלה, או באמצע, או בסוף.

רישום 4:


import re


listOfPlaces = ["Bayswater", "Table Bay", "Bejing", "Bombay"]


pattern = re.compile("[Bb]ay")

for place in listOfPlaces:
    if pattern.search(place):
        print (f"{place} matches the search pattern")

הפלט הוא כדלקמן, והוא תואם את "Bayswater", "Table Bay" ו-"Bombay" מרשימת המקומות:

$ python3 comparing-strings-re.py
Bayswater matches the search pattern
Table Bay matches the search pattern
Bombay matches the search pattern

השוואות מרובות שורות ורשימות

עד כה ההשוואות שלנו היו רק על כמה מילים. משתמש ב difflib מודול Python מציע גם דרך להשוות מחרוזות מרובות שורות ורשימות שלמות של מילים. ניתן להגדיר את הפלט לפי פורמטים שונים של כלים שונים.

הדוגמה הבאה (רישום 5) משווה בין שתי מחרוזות מרובות שורות שורה אחר שורה, ומציג מחיקות כמו גם הוספות. לאחר האתחול של Differ אובייקט בשורה 12 ההשוואה מתבצעת באמצעות ה- compare() שיטה בשורה 15. התוצאה מודפסת על הפלט הסטנדרטי:


import difflib
 


original = ["About the IIS", "", "IIS 8.5 has several improvements related", "to performance in large-scale scenarios, such", "as those used by commercial hosting providers and Microsoft's", "own cloud offerings."]


edited = ["About the IIS", "", "It has several improvements related", "to performance in large-scale scenarios."]


d = difflib.Differ()
 

diff = d.compare(original, edited)
 

print ('n'.join(diff))

הפעלת הסקריפט יוצרת את הפלט כפי שנראה להלן. שורות עם מחיקות מסומנות על ידי - סימנים ואילו שורות עם תוספות מתחילות בא + סִימָן. יתר על כן, שורות עם שינויים מתחילות בסימן שאלה. שינויים מסומנים באמצעות ^ שלטים במיקום המתאים. קווים ללא מחוון עדיין זהים:

$ python comparing-strings-difflib.py
  About the IIS
  
- IIS 8.5 has several improvements related
?  ^^^^^^

+ It has several improvements related
?  ^

- to performance in large-scale scenarios, such
?                                        ^^^^^^

+ to performance in large-scale scenarios.
?                                        ^

- as those used by commercial hosting providers and Microsoft's
- own cloud offerings.

סיכום

במאמר זה למדת דרכים שונות להשוות מחרוזות ב-Python. אנו מקווים שסקירה כללית זו תעזור לך לתכנת ביעילות בחיי המפתח שלך.

תודות

הכותבת רוצה להודות למנדי נוימאייר על תמיכתה במהלך הכנת המאמר.

בול זמן:

עוד מ Stackabuse