String işlemleri
Programlarda birçok veri sayı değildir: adlar, e-posta adresleri, ürün kodları, şehir adları, dosya adları ve kullanıcı mesajları metin olarak tutulur. Python’da metin değerlerine string denir, türleri str’dir.
Bu hafta bir string’in karakterlerine erişmeyi, parçalarını almayı, metni temizlemeyi ve basit kontroller yapmayı öğreneceğiz. String metotlarını ezberlemeniz gerekmez. Metni adım adım dönüştürüp her adımın sonucuna bakmanız yeter.
Bu sayfadaki kod hücreleri kendiliğinden çalışmaz. Her hücrede önce çıktıyı tahmin edin, sonra Run Code düğmesine basın. Kodu değiştirip yeniden çalıştırabilir, Start Over ile ilk hâline döndürebilirsiniz.
Bu bölümün kapsamı
- İndeks ve negatif indeksle karaktere erişim
- Dilimlemede başlangıcın dâhil, bitişin hariç olması
- String’in değiştirilemez olması ve metotların yeni string döndürmesi
strip(),lower(),upper()ve TürkçeI/İsınırıin,startswith()veendswith()denetimlerinin farkısplit()vejoin()ile parçalama ve birleştirme- f-string ile biçimlendirme ve
:.2fdavranışı
- Düzenli ifadeler (
remodülü) - Unicode normalleştirme biçimleri
casefold()davranışının ayrıntıları
Bu başlıklar konunun devamıdır. İleride karşınıza çıkar, ama bu derste ezberlemeniz beklenmiyor.
Kulübün kayıt listesini nasıl temizlerdiniz?
Okulda bir kulüp çevrim içi bir formla üye topluyor. Her öğrenci adını, öğrenci numarasını ve e-posta adresini yazıyor, aralarına virgül koyuyor. Formdan gelen liste şöyle:
Işıl Kaya,2406044,[email protected]
Deniz Yılmaz, 2306012 ,[email protected]
Ali Can,2506101,[email protected]
IŞIL KAYA ,2406044,[email protected]
Kulüp başkanı bu listeyi her hafta elle düzenliyor:
- Her satırı ad, numara ve e-posta diye üç parçaya ayırıyor.
- Numaranın ilk iki hanesinden öğrencinin giriş yılını buluyor:
23ise 2023. - Yalnız okul adresiyle, yani
omu.edu.trile biten adresle kaydolanları kabul ediyor. - Aynı kişi iki kez yazılmışsa birini siliyor.
- Temiz listeyi
Deniz Yılmaz (2023 girişli)biçiminde yazıyor.
Bu iş bir programa verilecek. Program yalnız ona yazdığınız kuralları bilecek. 1. bölümde bir işin adımlarını sözde kodla yazmıştık. Başkanın kurallarını da öyle, Türkçe ve madde madde yazın. Sonra kurallarınızı listedeki satırlarla deneyin:
- İkinci satırdaki öğrencinin giriş yılını kurallarınız kaç buluyor?
- Üçüncü satırdaki adresi kurallarınız okul adresi sayıyor mu?
- Birinci ve dördüncü satırı kurallarınız aynı kişi sayıyor mu?
Python bilmeniz gerekmiyor: “Satırı virgüllerden ayır” da bir kural. Kurallarınızı bir kenara yazın. Bölümde her birinin Python’da nasıl yazıldığını göreceğiz. Alıştırmalardan önce listenize döneceğiz.
String: karakterlerden oluşan bir değer
Aşağıdaki değişken bir string tutar:
sehir = "Samsun"Karakterleri soldan sağa numaralayalım:
S a m s u n
0 1 2 3 4 5
Her karakterin sırasını gösteren bu numaraya indeks denir. Python’da indeksler 0’dan başlar. Bir karaktere köşeli parantezle ulaşırız: sehir[0]. Hücredeki üç satır ne yazar?
Altı karakterlik bir string’in son geçerli pozitif indeksi 5’tir. sehir[6] yazmak IndexError hatası verir.
len() ile uzunluk
len() string içindeki karakter sayısını verir. Hücre kaç yazar?
Son indeks her zaman uzunluktan bir eksiktir:
uzunluk = 6
son indeks = 5
Bu nedenle son karaktere pozitif indeksle ulaşmak için len(metin) - 1 kullanılabilir. Hücre hangi karakteri yazar?
Bunun daha kısa bir yolu da var: hemen aşağıda göreceğimiz negatif indeksleme ile son karakteri metin[-1] yazarak alabiliriz.
Negatif indeksler
Negatif indeksler sağdan sayar: -1 son karakteri gösterir. İki satır ne yazar?
Tahmin et: hangi karakterler yazılır?
Kodu çalıştırmadan önce sonucu tahmin edin:
Sonra hücreyi çalıştırıp tahmininizi doğrulayın.
Dilimleme (slicing)
Bir string’in tek bir karakterini alabildiğimiz gibi bir bölümünü de alabiliriz. Buna dilimleme denir. Köşeli parantezin içine başlangıç ve bitiş indeksi iki noktayla ayrılarak yazılır. Hücre ne yazar?
Dilimlemede başlangıç indeksi dâhil, bitiş indeksi hariçtir.
metin[0:7]
↑ ↑
| └─ 7 dâhil değil
└─── 0 dâhil
Başlangıç ya da bitiş boş bırakılabilir. Başlangıç boşsa dilim metnin başından, bitiş boşsa metnin sonuna kadar alınır. İki satır ne yazar?
Alıştırma: ders kodunu parçalayın
"BLP101" değerinden ilk üç karakteri ve son üç karakteri ayrı değişkenlere alın.
Beklenen çıktı:
BLP
101
İlk üç karakter için ders_kodu[:3], son üç karakter için ders_kodu[-3:] kullanılabilir.
ders_kodu = "BLP101"
bolum = ders_kodu[:3]
numara = ders_kodu[-3:]
print(bolum)
print(numara)String değerler değiştirilemez
Gelecek hafta bir listenin elemanlarını değiştirebildiğimizi göreceğiz. String’in tek bir karakterini ise doğrudan değiştiremeyiz. Hücredeki ikinci satır ne yapar?
İkinci satır TypeError verir: 'str' object does not support item assignment. Python bir string’in karakterine atama yapmaya izin vermez. Hata çıktığı için print() satırına hiç gelinmez.
Bunun yerine yeni bir string oluştururuz. "K" ile metin[1:] dilimini + ile birleştiriyoruz. Hücre ne yazar?
Bir string oluşturulduktan sonra içeriği değişmez. Bu yüzden string’lere değiştirilemez (immutable) denir. String metotları da var olan değeri değiştirmez, yeni bir string döndürür.
lower(), upper() ve strip()
Metin karşılaştırmalarında büyük ve küçük harf farkı ve fazladan boşluklar sorun çıkarabilir. Bir string’in metodu, değerin arkasına nokta konarak çağrılır: girdi.strip(). Hücredeki iki satır ne yazar?
strip()baştaki ve sondaki boşlukları kaldırır.lower()harfleri küçük harfe çevirir. Bunu, bütün diller için ortak olan Unicode kurallarına göre yapar (Unicode, bilgisayarların dünyadaki yazı sistemlerindeki karakterleri numaralandırdığı standarttır).upper()aynı kurallarla harfleri büyük harfe çevirir.
Metni karşılaştırmadan önce böyle ortak bir biçime getirmeye normalleştirme denir.
Şu kod ne yazar?
Python yazar. lower() yeni bir string döndürür, ama bu sonuç hiçbir değişkene atanmadığı için kaybolur. metin eski değerini korur. Sonucu kullanmak için atama gerekir:
metin = metin.lower()Türkçe I ve İ harfleri
Bilgisayarınızın dil ve bölge ayarı (yerel ayar) Türkçe olsa bile str.lower() ve str.upper() Türkçe kurallarını kullanmaz. İki metot da her dilde aynı çalışan Unicode dönüşümünü uygular. Türkçede noktalı ve noktasız i ayrı harfler olduğu için bu fark gerçek veride sorun çıkarır.
Dört satır ne yazar? Özellikle ikinci satırı düşünün.
İlk satır ekranda iğne gibi görünebilir, ama i harfinden sonra gizli bir karakter daha vardır: birleşen nokta (U+0307), yani önündeki harfin üstüne eklenen nokta işareti. Bu yüzden ikinci satır False yazar: iki metin gözle aynı görünse de eşit değildir. len("İĞNE".lower()) sonucu 4 değil 5’tir.
Üçüncü satır ısparta değil isparta, dördüncü satır İSTANBUL değil ISTANBUL yazar.
Türkçede ise dönüşümler şöyle olmalıdır:
I→ıİ→ii→İı→I
casefold(), büyük ve küçük harfi önemsemeden karşılaştırma yapmak için lower()’dan daha kapsamlı bir Unicode metodudur. Ama Türkçeye özgü I ve İ sorununu o da çözmez. “lower() yerine casefold() yazarsam Türkçe sorunu biter” diye düşünmeyin.
Programınızın Türkçe büyük ve küçük harf kurallarına göre karşılaştırma yapması gerekiyorsa dönüşümü kendiniz yazabilirsiniz. Hücre hata vermeden biterse iki assert de geçmiştir:
Bu yardımcı fonksiyon önce Türkçeye özgü iki büyük harfi (I ve İ) kendisi küçültür, kalan harfler için de normal lower() kullanır.
Bu fonksiyonu her metne uygulamayın. E-posta alan adları, değişken ve fonksiyon adları ya da uluslararası kodlar Türkçe kurallar yerine başka kurallar gerektirebilir. Önce verinin hangi dilin kurallarına göre karşılaştırılacağına karar verin, sonra dönüşümü seçin.
İncele ve düzelt: temizlenmiş kullanıcı adı
Aşağıdaki kod kullanıcı adını temizlemeye çalışıyor, ama metotların döndürdüğü değeri hiçbir değişkene atamıyor. Düzeltmeden önce çalıştırın: ne yazıyor?
Çıktının deniz olması için kodu düzeltin.
kullanici_adi = kullanici_adi.strip().lower() yazabilirsiniz.
kullanici_adi = " DENIZ "
kullanici_adi = kullanici_adi.strip().lower()
print(kullanici_adi)in ile içerme kontrolü
Bir string’in başka bir string içerip içermediğini in ile kontrol edebiliriz. Üç satır ne yazar?
Sonuçlar bool türündedir.
“Bu parça metnin içinde geçiyor mu?” ile “Metin bu parçayla mı bitiyor?” iki ayrı sorudur. endswith() ikinci soruyu sorar, aşağıda ayrıca göreceğiz. Bu dosya adı için iki satır ne yazar?
Dosya uzantısını denetlerken işinize yarayan ikinci sorudur.
"@" in eposta ifadesinin True olması, metnin geçerli bir e-posta adresi olduğunu göstermez: "@@@" da bu kontrolden geçer. Basit bir kontrolü tam doğrulama sanmayın.
startswith(), endswith() ve replace()
Metnin başına ya da sonuna bakmak istiyorsanız in yerine bu iş için yazılmış metotları kullanın:
startswith(...): metin verilen başlangıçla mı başlıyor?endswith(...): metin verilen sonla mı bitiyor?
İki satır ne yazar?
Metnin içindeki bir parçayı başka bir parçayla değiştirmek için replace() kullanılır. Sonuç yeni bir string’dir. Hücre ne yazar?
String’ler değiştirilemez olduğu için replace() de var olan string’i değiştirmez. Sonucu bir değişkene atamak gerekir.
split() ile parçalama, join() ile birleştirme
Bir metni parçalara ayırmak için split() kullanılır. Parçaları birbirinden ayıran karaktere (örneğin virgüle) ayraç denir. split() parçaları bir liste olarak döndürür: köşeli parantez içinde, virgülle sıralanmış değerler. Listeleri gelecek hafta ayrıntısıyla göreceğiz. Hücre ne yazar?
Argüman vermezsek split() metni boşluklardan böler. Yan yana birden fazla boşluk varsa bunları tek ayraç sayar. Hücre ne yazar?
Tersi için, yani parçaları bir ayraçla birleştirip tek bir string elde etmek için join() kullanılır. Bu hücre ne yazar?
join() çağrısında soldaki string, parçaların arasına konacak ayraçtır.
split(",") içeriğini bildiğiniz basit metinlerde işe yarar. Gerçek CSV dosyalarında (değerlerin virgülle ayrıldığı tablo dosyaları) ise yanılabilir, çünkü bir alanın içinde de virgül ya da tırnaklı metin olabilir. 12. haftada bu iş için Python’ın csv modülünü kullanacağız.
String ve döngüler
Bir string üzerinde for ile karakter karakter gezebiliriz. Hücre kaç satır yazar?
Örneğin bir metindeki ASCII rakamlarını, yani 0–9 arasındaki rakamları sayalım. Karakterler de sayılar gibi >= ve <= ile karşılaştırılabilir. Hücre kaç yazar?
Python’da hazır .isdigit() metodu da vardır. Bu metot yalnız tek karakterde değil, bütün bir string’de de çalışır ve string’in rakamlardan oluşup oluşmadığını söyler. Dört satır ne yazar?
.isdigit(), 0–9 dışındaki bazı Unicode rakamları için de True döndürebilir (örneğin üs olarak yazılan "²"). Programınız yalnızca 0–9 rakamlarını kabul edecekse "0" <= karakter <= "9" gibi açık bir kontrol bu kuralı doğrudan yazar. Hazır bir metodu seçmeden önce, 7. haftadaki gibi, fonksiyonunuzun sözleşmesinin (fonksiyonun ne beklediğini ve ne döndürdüğünü söyleyen not) hangi karakterleri kabul ettiğine bakın.
Alıştırma: belirli karakteri sayın
Bir ürün kodunda kaç tane - karakteri bulunduğunu sayın.
Beklenen sonuç 3’tür.
if karakter == "-": koşulu içinde tire_sayisi değerini artırın.
urun_kodu = "TR-55-A-20"
tire_sayisi = 0
for karakter in urun_kodu:
if karakter == "-":
tire_sayisi = tire_sayisi + 1
print(tire_sayisi)f-string ile okunabilir çıktı
Tırnaktan önce f harfi yazılan string’e f-string denir. F-string, değişkenleri metnin içine yerleştirmenin okunaklı bir yoludur: değişkenler süslü parantezin içine konur. Hücre ne yazar?
Süslü parantezlerin içine ifadeler de yazılabilir. Bu kez ne yazar?
Sayıyı iki ondalık basamakla göstermek
2. haftadaki gezi hesabında kişi başı ücret 257.14285714285717 çıkmıştı. Bunu ekranda 257.14 TL biçiminde göstermeyi bu haftaya bırakmıştık. F-string içinde değişken adından sonra yazılan :.2f, sayıyı iki ondalık basamakla gösterir. İki satır ne yazar?
İlk satır Toplam: 257.14 TL yazar: fazladan basamaklar gösterilmez. İkinci satır Oran: 3.50 yazar: 3.5 iki basamağa tamamlanır.
.2f yalnızca sayının nasıl gösterileceğini belirler. tutar değerini metne çevirirken iki basamakla yazar. Değişkenin bellekteki değeri değişmez ve kesin bir ondalık sayıya dönüşmez. 7. haftada testlerde tolerans kullanmamızın nedeni de buydu.
Bu derste f-string’i çoğunlukla ekrana yazdırırken kullanacağız. Uzun hesapları süslü parantezin içine yazmak yerine önce ayrı bir değişkende hesaplayın. Kod daha kolay okunur.
Fonksiyonlarla metin normalleştirme
Aynı temizleme adımlarını birçok yerde kullanacaksak onları bir fonksiyona koyabiliriz. Hücre hata vermeden biterse iki assert de geçmiştir:
Bu örnekteki kullanıcı adlarında Türkçeye özgü harf yok. Türkçe ürün, kişi ya da şehir adlarını büyük ve küçük harfi önemsemeden eşleştirecekseniz yukarıdaki I ve İ kuralını da hesaba katmalısınız.
Bu fonksiyon saftır: bir string alır, yeni bir string döndürür ve dışarıdaki hiçbir değeri değiştirmez.
Soruya dönelim: kayıt listesi Python’da
Bölümün başında kulüp başkanının kurallarını yazıp üç satırla denemiştiniz. Python’daki karşılıkları şöyle:
| İş | Sözde kodda | Python’da | Dikkat |
|---|---|---|---|
| Satırı parçalamak | “Satırı virgüllerden ayır” | parcalar = satir.split(",") |
Virgülün yanındaki boşluk parçada kalır: ikinci satırın numarası " 2306012 " olur |
| Giriş yılı (2. satır) | “Numaranın ilk iki hanesini al” | numara.strip()[:2] |
Boşluk temizlenmezse numara[:2] sonucu " 2" olur. [:2] iki karakter alır, çünkü bitiş hariçtir |
| Okul adresi (3. satır) | “Adreste omu.edu.tr var mı bak” |
eposta.strip().endswith("@omu.edu.tr") |
in ile bakarsanız [email protected] da geçer. Kural “ile biten” diyor |
| Aynı kişi mi (1. ve 4. satır) | “İki adı da küçük harfe çevir, karşılaştır” | turkce_kucult(ad1.strip()) == turkce_kucult(ad2.strip()) |
lower() IŞIL adını işil, Işıl adını işıl yapar ve iki sonuç eşit çıkmaz. Sondaki boşluk da eşitliği bozar |
| Temiz satırı yazmak | “Adı yaz, yanına giriş yılını yaz” | yil = "20" + numara[:2], sonra f"{ad} ({yil} girişli)" |
Metotlar yeni string döndürür. ad.strip() yazıp sonucu atamazsanız yazdırılan ad temizlenmemiş kalır |
Listenizi tabloyla karşılaştırın. Kurallarınızda “boşlukları sil” adımı yoksa ikinci satırın giriş yılı yanlış çıkar. Okul adresini “içinde geçiyor mu” diye sınadıysanız üçüncü satır kabul edilir. Adları “küçük harfe çevir” diye eşlediyseniz insan için aynı olan iki ad Python için farklı kalır: kural doğru, ama Python’ın küçültmesi Türkçe kurallara uymaz.
Üret: basit kurumsal e-posta kontrolü
Kulüp başkanının üçüncü kuralını bir fonksiyona dönüştürün. kurumsal_eposta_mi adlı fonksiyon:
- Baştaki ve sondaki boşlukları temizlemeli
- Metni küçük harfe çevirmeli
- Metinde
@bulunup bulunmadığını kontrol etmeli - Metnin
omu.edu.trile bitip bitmediğini kontrol etmeli
Başlangıç kodu:
Beklenen çıktı:
True
False
False
Örneğin temiz = eposta.strip().lower() ile başlayabilirsiniz. Sonra "@" in temiz ve temiz.endswith("omu.edu.tr") koşullarını and ile birleştirin.
def kurumsal_eposta_mi(eposta):
temiz = eposta.strip().lower()
return "@" in temiz and temiz.endswith("omu.edu.tr")
print(kurumsal_eposta_mi(" [email protected] "))
print(kurumsal_eposta_mi("[email protected]"))
print(kurumsal_eposta_mi("[email protected]"))Bu fonksiyon yalnızca ders için basitleştirilmiş bir kontroldür. Gerçek e-posta adresi doğrulaması için daha ayrıntılı kurallar gerekir.
Sıra sizde: kayıt satırını temizleyin
Kulüp başkanının bütün kurallarını tek bir satıra uygulayın. Program satırı üç parçaya ayırsın, her parçanın boşluğunu temizlesin, okul adresi değilse Kabul edilmedi yazsın, okul adresiyse adı ve giriş yılını Deniz Yılmaz (2023 girişli) biçiminde yazsın.
Programı bölümün başındaki dört satırla deneyin. Beklenen sonuçlar:
satir |
Beklenen |
|---|---|
Işıl Kaya,2406044,[email protected] |
Işıl Kaya (2024 girişli) |
Deniz Yılmaz, 2306012 ,[email protected] |
Deniz Yılmaz (2023 girişli) |
Ali Can,2506101,[email protected] |
Kabul edilmedi |
IŞIL KAYA ,2406044,[email protected] |
IŞIL KAYA (2024 girişli) |
parcalar = satir.split(",") ile başlayın. Sonra ad = parcalar[0].strip() gibi her parçayı ayrı bir değişkene alın. Giriş yılı için numaranın ilk iki karakterini "20" ile birleştirin.
satir = "Deniz Yılmaz, 2306012 ,[email protected]"
parcalar = satir.split(",")
ad = parcalar[0].strip()
numara = parcalar[1].strip()
eposta = parcalar[2].strip().lower()
if eposta.endswith("@omu.edu.tr"):
yil = "20" + numara[:2]
print(f"{ad} ({yil} girişli)")
else:
print("Kabul edilmedi")Tek sayfa özet
Bu hafta string’leri parçalara ayırdık, temizledik ve kontrol ettik.
- String indeksleri
0’dan başlar. - Negatif indeksler sağdan sayar; son karakter
metin[-1]ile alınabilir. len()karakter sayısını verir.- Dilimlemede başlangıç dâhil, bitiş hariçtir.
- String değerler değiştirilemez; metotlar yeni string döndürür.
strip(),lower()veupper()metni karşılaştırmadan önce ortak bir biçime getirir.lower()veupper()Türkçeye özgüIveİdönüşümünü yapmaz:"IŞIL".lower()sonucu"işil"olur.casefold()büyük ve küçük harfi önemsemeyen karşılaştırmalarda işe yarar ama TürkçeIveİsorununu çözmez.inbir parçanın metnin herhangi bir yerinde geçip geçmediğine bakar;startswith()veendswith()yalnızca başa ya da sona bakar.replace()bir parçası başka bir parçayla değiştirilmiş yeni bir string döndürür.split()metni parçalara ayırır,join()string parçaları bir ayraçla birleştirir.forile bir string’in karakterleri tek tek gezilebilir;.isdigit()bir string’in rakamlardan oluşup oluşmadığını söyler.- F-string değişkenleri metnin içine yerleştirir;
:.2fsayıyı iki ondalık basamakla gösterir. - Tekrarlanan temizleme ve kontrol adımları bir fonksiyona konabilir.
- Gerçek veride bir satır çoğu zaman birkaç adımda temizlenir: önce
split(), sonra her parçadastrip(), en son karşılaştırma.
Bir sonraki bölümde birden fazla değeri birlikte tutmak için listeler ve demetler kullanacağız.
Bu bölümün kazanımları
Bu bölümü bitiren öğrenci:
- İndeks ve negatif indeksle karaktere erişir.
- Dilimlemede başlangıcın dâhil, bitişin hariç olduğunu hesaba katarak dilim alır.
- String’in değiştirilemez olduğunu ve metotların yeni string döndürdüğünü açıklar.
strip(),lower()veupper()ile normalleştirir; TürkçeI/İsınırını açıklar.in,startswith()veendswith()denetimlerini ayırt eder.split()vejoin()ile metni parçalar ve birleştirir.- F-string ile biçimlendirir ve
:.2fdavranışını açıklar.