Python'da düzenli ifadelerle metin temizleme: re modülü rehberi
Beceri rehberi

Python'da düzenli ifadelerle metin temizleme: re modülü rehberi

Hazırlayan: Mindset Institute EditörlüğüGüncellendi: 6 dk okuma

Python'ın re modülüyle metin temizlemeyi öğrenin: re.sub, re.findall, bayraklar, ham metin, Türkçe karakter tuzakları ve pandas'ta toplu uygulama.

Regex ne zaman doğru araçtır?

Düzenli ifade (regular expression), metin içinde bir örüntüyü tarif etmenin kısa yoludur: "boşluk dizileri", "etiketler arasındaki her şey", "e-posta benzeri parçalar". Python'da bu işlerin hepsi standart kütüphanedeki re modülüyle yapılır.

Her metin işi regex gerektirmez. Sabit bir ifadeyi değiştirmek için str.replace, baştan sondan boşluk silmek için strip yeterlidir. Regex ise örüntü değişkense devreye girer: değişken sayıda boşluk, farklı yazılmış telefon numaraları, bilinmeyen içerikli etiketler. Karşı tarafta, HTML ya da JSON gibi iç içe yapılı biçimleri regex ile çözmeye çalışmak kırılgandır; bunlar için ayrıştırıcı kullanılır.

Pratik kural: Örüntü basit ve tekrarlıysa regex, yapı iç içe ise ayrıştırıcı, sabit metinse str yöntemleri. Veri temizleme işlerinde regex en çok şu işler için kullanılır: Gereksiz karakterleri silmek, biçimi normalleştirmek (telefon, boşluk, noktalama) ve metinden belirli parçaları çıkarmak (e-posta, referans numarası).

Temel işlevler ve ham metin yazımı

Python belgesine göre sık kullanılan işlevler şunlardır:

  • re.search(pattern, string): Metin içinde örüntünün ilk eşleştiği yeri arar; bulursa Match nesnesi, bulamazsa None döndürür.
  • re.findall(pattern, string): Üst üste binmeyen bütün eşleşmeleri liste olarak verir. Örüntüde grup yoksa tüm eşleşme metinleri, bir grup varsa o grubun metinleri, birden çok grup varsa demetler döner.
  • re.sub(pattern, repl, string): Eşleşen bölümleri repl ile değiştirir; repl bir metin ya da bir işlev olabilir. count sıfırsa tümü değiştirilir.
  • re.compile(pattern): Örüntüyü derler ve aynı örüntüyü çok kez kullanacaksanız tekrar tekrar çözümleme maliyetini azaltır.

Örüntüleri her zaman ham metin (raw string) olarak yazın, yani tırnağın önüne r koyun: r"\s+" gibi. Belgeye göre ham metinde ters bölü özel işlenmez; aksi halde Python'un kendi kaçış dizileri düzenli ifadeyle karışır ve örüntü beklediğiniz gibi çalışmaz. Çoğu hatalı regex'in nedeni budur.

Temel yapı taşları: \s boşluk benzeri karakter, \d rakam, \w harf-rakam-alt çizgi; büyük harfli karşılıkları (\S, \D, \W) bunların tersidir. Belgeye göre bu diziler metin örüntülerinde Unicode karakterleri de kapsar; yani \w Türkçe harfleri (ç, ğ, ş gibi) de eşleştirir. Bu, Türkçe metin temizliğinde işi kolaylaştırır.

Adım adım: gürültülü bir metin alanını temizlemek

Örneğin müşteri notlarının bulunduğu bir metin sütununu temizleyeceksiniz. Girdiler kopyala-yapıştırdan geldiği için fazla boşluk, satır sonu, HTML kalıntısı ve garip semboller içeriyor.

import re html_etiketi = re.compile(r"<[^>]+>") bosluklar = re.compile(r"\s+")

def temizle(metin): metin = html_etiketi.sub(" ", metin) metin = bosluklar.sub(" ", metin) return metin.strip()

Birinci kural satır sırasıdır: Önce HTML etiketlerini silin, çünkü etiketler boşluk bırakır. Ardından ardışık boşluk, sekme ve satır sonu karakterlerini tek boşluğa indirin. En sonda baştaki ve sondaki boşlukları strip ile kesin. <[^>]+> örüntüsü "açılan işaretle başlayıp kapanan işarete kadar, arada kapanan işaret olmayan her şey" demektir; basit etiketler için yeterlidir.

Bir adım daha: noktalama temizliği. Harf, rakam ve boşluk dışındaki her şeyi silmek için re.sub(r"[^\w\s]", "", metin) kullanılır. Ancak bu, tireyi, kesme işaretini ve yüzde işaretini de siler; tarih, ürün kodu ve oran gibi bilgilerin bozulmasına yol açar. Silinecek karakterleri sınırlamak gerekebilir. Bu yüzden temizleme kurallarını, sonuçları tek tek gözle denetleyerek yazın.

Belirli parçaları çıkarmak: findall ve gruplar

Temizlik yalnızca silmek değildir; bazen metinden istenen parçayı ayıklarsınız. E-posta benzeri parçaları bulmak için:

adaylar = re.findall(r"[\w.+-]+@[\w-]+\.[\w.]+", metin)

Bu örüntü basit bir ayıklayıcıdır; geçerli e-posta doğrulaması yapmaz. Doğrulama gerekiyorsa ayrı bir kütüphane ya da gönderim sırasındaki doğrulama kullanılır. Regex'le "yaklaşık bulma" ve "kesin doğrulama" farklı işlerdir.

Gruplar parçaları ayrı ayrı yakalar. Parantezli bölümler bir grup oluşturur ve isim verilebilir:

eslesme = re.search(r"(?P<on_ek>[A-Z]+)-(?P<numara>\d+)", metin) if eslesme: kod = eslesme.group("numara")

Burada "ABC-numara" biçimindeki bir kodun harf kısmı ve sayı kısmı ayrı çekilir. findall'a birden çok grup verirseniz belgeye göre demetler listesi döner; bunu pandas tablosuna doğrudan çevirmek kolaydır.

Telefon numarası normalleştirmede yaklaşım şöyledir: Önce rakam olmayan her şeyi silin: re.sub(r"\D", "", numara). Sonra ülke ön ekini ve uzunluğu iş kuralınıza göre kontrol edin. Regex biçimi temizler; numaranın geçerli olup olmadığına ayrı bir kuralla karar verin.

Bayraklar, Türkçe karakter ve kaçış tuzakları

Bayraklar eşleşme davranışını değiştirir. Belgeye göre re.IGNORECASE (kısa adı re.I) büyük küçük harf ayrımını kaldırır; re.MULTILINE (re.M) ise satır başı ve satır sonu işaretlerini yalnızca metnin değil her satırın başı ve sonu için çalıştırır. Bayraklar | ile birleştirilir ve fonksiyonlara flags olarak verilir. Yeni Python sürümlerinde sub'a count ve flags değerlerini konumsal değil anahtar sözcükle vermeniz önerilir.

Türkçe için önemli bir tuzak vardır: Python'un büyük-küçük harf dönüşümü Türkçe kurallarını varsaymaz. "I" harfi küçültüldüğünde "i" olur, "ı" olmaz; "İ" ise ayrı bir harftir. Bu yüzden IGNORECASE ile "ISPARTA" ve "Isparta" gibi yazımları eşlemek Türkçe beklentinizle birebir örtüşmeyebilir. Büyük küçük harf duyarsız karşılaştırma önemliyse metni önce kendi dönüşüm tablonuzla normalleştirin (örneğin İ'yi i, I'yı ı yapan açık bir eşleme) ve sonra regex'e verin.

Diğer tuzaklar:

  • Noktanın her karakteri eşleştirmesi: Gerçek nokta için \. yazın.
  • Açgözlü eşleşme: .* mümkün olan en uzun parçayı alır. Etiketleri ayıklarken [^>]+ gibi sınırlı sınıflar ya da açgözlü olmayan .*? kullanın.
  • Aşırı karmaşık örüntü: İç içe tekrarlar bazı girdilerde çok yavaşlayabilir (geri izleme). Örüntüyü sade tutun, uzun metinlerde süreyi ölçün.
  • Okunamaz ifade: Karmaşık örüntüyü re.VERBOSE ile parçalara bölüp açıklama ekleyin; aylar sonra siz de okumak isteyeceksiniz.

Pandas'ta toplu uygulama ve test alışkanlığı

Gerçek veride regex genellikle bir tablonun metin sütunu üzerinde çalışır. Pandas, str erişimcisiyle bunu vektörel olarak yapar:

df["not_temiz"] = df["not"].str.replace(r"\s+", " ", regex=True).str.strip() df["etiket_var"] = df["not"].str.contains(r"<[^>]+>", regex=True) df["kod"] = df["not"].str.extract(r"(?P<kod>[A-Z]+-\d+)")

Yöntem eksik değerleri (NaN) hata vermeden geçer ve sonuç yine eksik kalır. Her satır için Python işlevi çağırmak yerine bu yöntemleri tercih edin; büyük tablolarda daha okunur ve genellikle daha hızlıdır.

Regex'i güvenle yazmak için küçük bir test alışkanlığı edinin: Birkaç gerçek ve bilerek bozuk örnek metin hazırlayın, her kural için beklenen çıktıyı yazın ve kuralı değiştirdiğinizde tümünü yeniden çalıştırın. Temizlik kuralları zamanla büyür; testi olmayan regex'ler bir düzeltme yaparken bir başkasını bozar.

Önce işaretleyin, sonra silin: Hangi satırların hangi kuraldan etkilendiğini sayıp örnekleyin. Ham veriyi koruyup temizlenmiş sütunu yanına ekleyin. Böylece bir kural hatalı çıktığında özgün metne dönebilirsiniz.

Bu beceriyi Mindset programlarında nerede çalışırsınız?

Regex ile metin temizleme; müşteri geri bildirimi, şikâyet kayıtları, ürün adları, adres alanları ve form girdileriyle çalışan analistler, veri mühendisleri ve raporlama ekipleri için günlük bir ihtiyaçtır. Metin alanındaki tutarsızlık, birleştirme ve gruplama sonuçlarını bozduğu için temizlik kuralları analizden önce, tekrar çalıştırılabilir biçimde yazılmalıdır.

Python ile Veri Temizleme programının modül başlıkları arasında veri kalitesi tanılama ve keşif, metin ve kategorik veri temizleme, veri dönüşümü ve yapılandırma ile tekrarlanabilir veri temizleme boru hatları yer alır. Regex kurallarını bir boru hattında sürümleyip test etmeyi isteyen ekipler için bu başlıklar birlikte çalışılabilir. Pandas tarafını güçlendirmek isteyenler için Python ile Veri Analizi (Pandas) programı da tamamlayıcıdır.

İlgili Mindset programı

Python ile Veri Temizleme

Sık sorulanlar

Sık sorulan sorular

re.sub ile str.replace arasındaki fark nedir?

str.replace sabit bir metni değiştirir. re.sub ise bir örüntüyü, yani değişken uzunluk ve içerikte metinleri değiştirir ve değiştirme için işlev de kullanabilir. Sabit bir ifadeyse str.replace daha basit ve hızlıdır. Boşluk dizileri ya da etiketler gibi değişken örüntüler için re.sub gerekir.

Regex yazarken neden r önekiyle ham metin kullanılır?

Python metinlerinde ters bölü kaçış dizisi başlatır; \n yeni satır olur. Düzenli ifadelerde ise ters bölü kendi anlamlarını taşır. Ham metinde ters bölü özel işlenmediği için örüntü yazdığınız gibi gider. Böylece çift ters bölü yazma ihtiyacı ve karışıklık ortadan kalkar.

Python regex Türkçe karakterleri tanır mı?

Evet. Metin örüntülerinde \w gibi diziler Unicode harfleri kapsar, bu yüzden ç, ğ, ı, ö, ş, ü eşleşir. Dikkat edilecek nokta büyük küçük harf dönüşümüdür: I ve İ harfleri Türkçe kurallarına göre eşlenmez. Büyük küçük harf duyarsız eşleştirmede önce metni kendi tablonuzla normalleştirin.

Regex ile HTML temizlemek güvenli midir?

Basit etiketleri silmek için yeterlidir, ancak iç içe, hatalı kapanmış ya da özellik değerinde işaret içeren HTML'de kırılır. Metni yalnızca temizlemek istiyorsanız basit örüntü işe yarar; yapıyı okumak gerekiyorsa BeautifulSoup gibi bir HTML ayrıştırıcısını kullanın.

Karmaşık regex'i nasıl okunur ve test edilir hale getirmeli?

re.VERBOSE bayrağıyla örüntüyü satırlara bölüp açıklamalar ekleyin, anlamlı grup adları kullanın ve her kural için geçerli ile geçersiz örnekleri içeren küçük bir test listesi tutun. Kuralı değiştirdiğinizde bu listeyi yeniden çalıştırmak, bir hatayı düzeltirken yenisini yaratmayı önler.

Python Regex ile Metin Temizleme: re Modülü Örnekleri