2.36. Gruplar ve çapalar¶
Bir desen yalnızca “bu dize eşleşiyor” demekten fazlasını yapabilir; eşleşen parçaları birbirinden ayırabilir ve her birini ada göre uygulamaya verebilir. Bir desenin bir kısmını saran parantezler onu bir yakalama grubu yapar; eşleşme nesnesi ardından her grubu ayrı bir alt dize olarak açığa çıkarır.
2.36.1. Yakalama grupları¶
Eşleştirdiği şeyi yakalamak için bir desenin herhangi bir kısmını (...) içine alın:
>>> import re
>>> m = re.search(r'temp (\d+) at (\d+)s', 'temp 42 at 137s ok')
>>> m.group(0)
'temp 42 at 137s'
>>> m.group(1)
'42'
>>> m.group(2)
'137'
Grup 0 her zaman eşleşmenin tamamıdır.
Grup 1, 2, … yakalanan alt dizelerdir; açılış parantezlerine göre soldan sağa numaralandırılırlar.
Son grubun ötesindeki bir dizinle
match.group()çağrılmasıIndexErrorhatası fırlatır.
Yaygın bir desen şudur: “bilinen bir yapıyı eşleştir, değişken kısımları int olarak yakala”:
def parse_temp(line):
m = re.search(r'temp (\d+) at (\d+)s', line)
if not m:
return None
return int(m.group(1)), int(m.group(2))
2.36.2. Yakalamayan gruplar¶
Parantezler ayrıca bir alt ifadeyi gruplar, böylece bir niceleyici tüm gruba uygulanabilir. r'(ab)+' içinde gruplamanın tek amacı budur – “bir veya daha fazla ab“. ab‘nin grup 1 olarak görünmesi bir yan etkidir.
Yakalamadan gruplamak için (?:...) kullanın:
>>> re.search(r'(?:ab)+', 'xababy').group(0)
'abab'
Yakalamayan gruplar, bir desen yapı için gruplama kullandığında ancak her parçayı çekmeyi umursamadığında grup numaralarını düzenli tutar.
2.36.3. Çapalar¶
Çapalar bir karakteri eşleştirmez – bir konumu eşleştirir.
^– dizenin başlangıcı.$– dizenin sonu.
Çapalar, re.match() ve re.search() fonksiyonlarının farklı davranmasını sağlayan şeydir. re.match(p, s), re.search('^' + p, s) ile aynıdır: deseni 0. konumda başlamaya zorlar. Bir desenin sonuna $ eklemek ise deseni tüm dizeyle ve başka hiçbir şeyle eşleşmeye zorlar:
>>> re.search(r'^\d+$', '12345')
<match num=1>
>>> re.search(r'^\d+$', '12345 ok') is None
True
MicroPython re modülünde ^ ve $ her zaman re.search() fonksiyonuna geçirilen tüm dizenin başlangıcını ve sonunu ifade eder. Bunları her gömülü satır sonunda eşleştirmek için bir re.MULTILINE bayrağı yoktur ve $ sondaki bir \n öncesindeki konumu da eşleştirmez – girişin mutlak sonu olmak zorundadır. Satır başına davranış elde etmek için, girişi önce satır sonlarına göre bölün ve deseni her satırda çalıştırın.
2.36.4. Karakter kümeleri¶
Köşeli parantezler açık bir karakter kümesi tanımlar. Eşleşme kümeden tam olarak bir karakter tüketir.
[abc]–a,b,ckarakterlerinden biri.[a-z]–a-zaralığında (dahil) bir karakter.[a-zA-Z0-9]– harfler veya rakamlar. Birleştirilmiş üç aralık.[^abc]–a,b,ckarakterlerinden biri değil.^yalnızca parantezlerin içindeki ilk karakter olduğunda olumsuzlama yapar.
Örnekler:
>>> re.search(r'[A-F0-9]{6}', 'colour #1a2b3c rest').group(0)
'1A2B3C'
>>> re.search(r'[A-F0-9]{6}', 'colour #1a2b3c rest') is None
True
İlk çağrı pratikte None döndürür çünkü değişmez metin küçük harftir. MicroPython re modülünde re.IGNORECASE bayrağı yoktur – büyük/küçük harf duyarsız eşleştirme yapmak için her iki durumu da kümeye yazın:
>>> re.search(r'[A-Fa-f0-9]{6}', 'colour #1a2b3c rest').group(0)
'1a2b3c'
Sınıf kısayolları (\d, \s, \w ve bunların olumsuzlanmış biçimleri) [...] içinde de kullanılabilir: [\w-] “sözcük karakterleri veya değişmez bir tire” demektir.
2.36.5. Açgözlü ve tembel niceleyiciler¶
*, +, ? ve {m,n} niceleyicileri varsayılan olarak açgözlüdür – desenin geri kalanının hâlâ izin verdiği kadar çok karakteri eşleştirirler. Çoğu zaman istenen tam olarak budur; bazen değildir:
>>> re.search(r'<(.+)>', 'a <b> <c> d').group(1)
'b> <c'
Açgözlü .+ son >‘ye kadar her şeyi yakaladı. ? eklemek niceleyiciyi tembel yapar – mümkün olduğunca az eşleştirir:
>>> re.search(r'<(.+?)>', 'a <b> <c> d').group(1)
'b'
Tembel biçim ilk >‘de durur. Tembel niceleyiciler, bir dizeden dengeli sınırlayıcılar çıkarırken sürekli karşımıza çıkar.
2.36.6. Değiştirmede geri başvurular¶
re.sub(), değiştirme dizesinde \1, \2, … aracılığıyla yakalanan gruplara geri başvurabilir. Değiştirme, yakalanan parçaları kullanarak her eşleşmeyi yeniden yazar:
>>> re.sub(r'(\d+)\.(\d+)', r'\2.\1', 'swap 12.34 and 5.6')
'swap 34.12 and 6.5'
Her eşleşme iki sayı yakalar ve değiştirme bunların yerini değiştirir. \g<1> aynı şey için alternatif bir sözdizimidir – değiştirmedeki bir sonraki karakter bir rakam olduğunda kullanışlıdır (grup 1’e değişmez bir sıfır eklemek için r'\g<1>0', “grup 10” olarak okumak yerine).
2.36.7. Mevcut olmayanlar¶
CPython’dan gelen bir desenin buraya düşüp sizi şaşırtması ihtimaline karşı, MicroPython re modülünün desteklemediği şeylerin bir hatırlatması:
İleri bakış
(?=...)ve geri bakış(?<=...)– uygulanmadı.Adlandırılmış gruplar
(?P<name>...)ve adlandırılmış geri başvurular(?P=name)– uygulanmadı.re.IGNORECASE,re.MULTILINE,re.DOTALLgibi bayrak sabitleri – dikkate alınmaz. Büyük/küçük harf duyarsız kümeyi kendiniz oluşturun veya girişi önceden bölün.match.groups(),match.span(),match.start()vematch.end()metotları, gönderilen hiçbir OpenMV kartının etkinleştirmediği bir ROM düzeyine bağlıdır. Bunlara dayanan kod kamerada çalışmaz.
Desenler, gruplar ve çapalarla, kameradaki regex araç seti tek oturuşta öğrenilecek kadar küçük ve bağlama duyarlı ayrıştırma dışında her şeyi yapacak kadar zengindir.