Regex'e Ne Zaman Başvurulur
Düzenli ifadeler, metin desenlerini tanımlamak için kullanılan küçük bir dildir. Güçlüdürler ve fazla kullanması kolaydır.
re'ye uzanmadan önce düz string metotlarının işi görüp görmeyeceğini sor. .split(), .replace(), .startswith(), "target" in text — bunlar eşdeğer regex'ten daha hızlı, daha okunaklı ve hataya daha az açıktır. Regex'i, önemsediğin desen gerçekten yapılandırılmış ama sabit string işlemleri için fazla esnek olduğunda sakla: e-posta adresleri, telefon numaraları, şekli bilinen log satırları, HTML ya da Markdown parçaları, her türlü "şu şeyden bul" araması.
Temel Söz Dağarcığı
Bir regex deseni, aradığın şeyi tanımlayan bir string'dir. Birkaç yapı taşı:
.— herhangi tek bir karakter\d— herhangi bir rakam (0–9)\w— herhangi bir "kelime" karakteri (harf, rakam, alt çizgi)\s— herhangi bir boşluk karakteri^— string'in başı$— string'in sonu[abc]— a, b veya c'den biri[^abc]— a, b, c dışında herhangi bir karaktera|b— a veya b*— öncekinden sıfır veya daha fazla+— bir veya daha fazla?— sıfır ya da bir{3}— tam olarak 3{2,5}— 2 ile 5 arası( ... )— grup (içindeki eşleşmeyi yakalar)
Çoğu gerçek dünya regex'i için bu kadarı yeterlidir.
Anahtar Fonksiyonlar
re.search(pattern, text), string'in herhangi bir yerindeki ilk eşleşmeyi bulur. Bir match nesnesi ya da None döndürür:
Regex desenleri için her zaman raw string (r"...") kullan. Aksi halde Python ters bölüleri string kaçışları olarak yorumlamaya çalışır ve yazdığından farklı bir desen elde edersin.
re.match(pattern, text), search gibidir ama yalnızca başta eşleşir:
Çoğu zaman search istersin.
re.findall(pattern, text), tüm örtüşmeyen eşleşmeleri liste olarak döndürür:
findall'ın match nesneleri değil, string'ler döndürdüğüne dikkat et. Bir grubu olan bir desenin varsa, grup içeriklerini alırsın. Birden fazla grupla, tuple listesi alırsın.
Yakalama Grupları
Bir desendeki parantezler, içeride eşleşen her şeyi yakalar:
Adlandırılmış gruplar genelde daha nettir:
Regex'inde birden fazla grup olduğunda, onlara isim vermek çıkarma kodunu izlemesi çok daha kolay hale getirir.
re.sub ile Değiştirmek
re.sub(pattern, replacement, text) her eşleşmeyi değiştirir:
Bu, rakam olmayan her şeyi siler. Yerine konulan değer yakalanan grupları \1, \2 vb. ile referanslayabilir — ya da raw string'lerde \g<1> daha nettir:
Yerine konulan değer olarak bir fonksiyon da geçebilirsin. Bu, basit bir takas olmayan dönüşümler için kullanışlıdır:
Tekrar Kullanım İçin Desen Derlemek
Aynı deseni defalarca kullanıyorsan — özellikle bir döngüde — onu bir kez derle:
Derlenmiş desenler aynı metotları — search, match, findall, sub — ilk argüman olarak deseni vermeden sunar. Biraz daha verimli, çoğu zaman daha okunaklı.
Bayraklar
flags= argümanı olarak ya da VEYA ile birleştirilerek geçilen yaygın değiştiriciler:
re.IGNORECASE(re.I) — büyük/küçük harf duyarsız eşleşme.re.MULTILINE(re.M) —^ve$her satırda eşleşir, sadece string sınırlarında değil.re.DOTALL(re.S) —.satır sonlarıyla da eşleşir (varsayılan olarak eşleşmez).re.VERBOSE(re.X) — okunabilirlik için desende boşluk ve#yorum satırlarına izin verir.
re.VERBOSE özellikle karmaşık desenler için kullanışlıdır:
Çok satırlı, yorumlu regex'lerin bakımı, anlaşılmaz tek satırlıklarınkinden çok daha kolaydır.
Greedy ve Lazy
Niceleyiciler (*, +, ?, {n,}) varsayılan olarak greedy'dir — olabildiğince çoğunu eşler. Lazy yapmak için bir ? ekle:
Greedy versiyon <b>'den </i>'ye kadar tüm alt string'i yakalar — muhtemelen istediğin bu değildi. Lazy olan .+?, ilk >'da durur.
(Yan not: prodüksiyonda HTML'i regex ile ayrıştırma. html.parser ya da BeautifulSoup kullan. Yukarıdaki örnek sadece greedy'liği göstermek için.)
Gerçekçi Bir Örnek
Basit bir log formatından satırları ayrıştırmak:
Çok satır olmayan bir yerde bir hayli güç.
Birkaç Alışkanlık
- Desenler için her zaman raw string kullan.
- İşe yarayan en basit desenle başla; sonra sıkılaştır.
- Birden fazla grubun olduğu anda adlandırılmış gruplar kullan.
- Tekrar kullanacağın desenleri derle.
- Regex, düz string metotlarından yavaştır.
.split()iş görecekse.split()kullan.
Sırada: Hatalar ve Hata Ayıklama
Bu, gerçek veri turunu kapattı — dosyalar, JSON, CSV, HTTP, tarihler ve regex. Ama gerçek bir programda her şey er ya da geç bir hataya çarpar ve Python traceback'lerini iyi okumak, geliştireceğin tek en büyük hata ayıklama becerisidir. Son bölüm, istisnaları ve en sık karşılaşacağın belirli hataları konu alıyor.
Sıkça Sorulan Sorular
Python'da regex nedir?
Düzenli ifade (regex), metindeki desenleri tanımlamak için kullanılan küçük bir dildir. Python'un re modülü desen aramanı, parça çıkarmanı ve eşleşmeleri değiştirmeni sağlar. Basit string işlemleri için abartılıdır — önce .split() ya da .replace() gibi string metotlarını dene — ama yapılandırılmış desen eşleşmesinde emsalsizdir.
re.match ile re.search arasındaki fark nedir?
re.match yalnızca string'in başında eşleşir. re.search tüm string'i tarar ve herhangi bir yerdeki ilk eşleşmeyi bulur. Emin değilsen search kullan — insan sezgisine daha uyar.
Regex desenleri için hep raw string mi kullanmalıyım?
Evet. Regex desenleri genelde ters bölü karakterleri içerir (\d, \s, \b); Python string'leri bunları kaçış dizileri olarak yorumlar. Başına r eklemek — r'\d+' — Python'a string'i harfiyen alması gerektiğini söyler, böylece regex'in kendisi okunaklı kalır.