Yazmaçların Kullanımı
Önceki GNU Regex İşlevleri Sonraki
Yazmaçların Kullanımı
Bir düzenli ifade içindeki bir grup, düzenli ifadenin tamamen eşleştiği bir dizgenin alt dizgesi (muhtemelen boş) ile eşleşebilir. Eşleştirici, her bir grupla eşleşen alt dizgelerin başlangıç ve bitiş noktalarını hatırlar.
Onların nelerle eşleştiğini bulmak için bir GNU eşleştirme ve arama işlevinin yazmaçlar argümanına sıfırdan farklı bir değer, örneğin regex.h dosyasında tanımlı olan aşağıdaki gibi bir yapının adresini atayın:
struct re_registers
{
  unsigned  num_regs;
  regoff_t *start;
  regoff_t *end;
};
veri türü
num_regs'inci eleman hariç (aşağıya bakınız), start ve end dizilerinin i'nci elemanı, şablondaki i'nci grup hakkındaki bilgileri kaydeder. (Hiçbir C derleyicisi sıfır uzunluklu dizileri kabul etmediğinden bu diziler gösterici olarak bildirilmiştir; kavramsal olarak, onları dizi olarak düşünmek en kolayıdır.)
start ve end dizileri için, eşleştiriciye aktarılan şablon tamponu içindeki regs_allocated alanının değerine bağlı olarak çeşitli yöntemlerle bellek ayrılabilir.
Burada uygulanması en basit ve belki de en akıllıca yöntem; eşleştiriciye, düzenli ifade içindeki bütün grupların bilgilerinin kaydedilebileceği alanı (yeniden) ayırmaktır. regs_allocated alanının değeri REGS_UNALLOCATED ise, eşleştirici 1 + re_nsub yer tahsis eder (şablon tamponu içindeki bir alan). Ek elemana -1 ve regs_allocated alanına REGS_REALLOCATE değeri atanır. Daha sonradan aynı şablon tamponu ve yazmaçlar argümanıyla yapılan çağrılarda, eşleştirici gerektiği kadar alanı yeniden tahsis eder.
regs_allocated alanını re_registers yapısının bir parçası yapmak, şablon tamponun bir parçası yapmaktan daha akıllıca bir yöntem olabilir. Fakat bu durumda, çağrıcıya aktarılmadan önce yapının ilklendirilmesi zorunlu olacaktı. Mevcut kodların pek çoğu bu ilklendirmeyi yapmaz ve bundan kaçınmak her halükarda en iyisidir.
re_compile_pattern, regs_allocated alanına REGS_UNALLOCATED atar, böylece GNU düzenli ifade işlevlerini kullanırsanız, bu davranışı öntanımlı olarak elde etmiş olursunuz.
Diğer yandan, POSIX, farklı bir arayüze ihtiyaç duyar: çağrıcı, eşleştirici tarafından doldurulacak sabit uzunluktaki bir dizi aktarılacağını varsayar. Bu nedenle, şayet regs_allocated alanının değeri REGS_FIXED ise, eşleştirici o diziyi doldurur.
Aşağıdaki örneklerde, re_registers yapısına bilgi kaydedilmesi gösterilmiştir. (Hepsinde, ( işlecinin grup başlatma, ) işlecinin ise grup sonlandırma işleci olduğu varsayılmıştır. dizge dizgesinin ilk karakterinin indisi 0 dır.)
  • Şayet düzenli ifade, dizge dizgesinin bir alt dizgesi ile eşleşen ve bir alt grup içermeyen bir i'inci grup içeriyorsa, işlev, yazmaçlar->start[i] alanını dizge içindeki, i'inci grupla eşleşen altdizgenin başlangıcına, yazmaçlar->end[i] alanını da alt dizgenin sonuna denk gelen indise ayarlar. İşlev, yazmaçlar->start[0] ve yazmaçlar->end[0] alanlarını ise şablonun tamamı hakkındaki benzer bilgilere ayarlar.
    Örneğin, ((a)(b)) ifadesini ab dizgesi ile eşleştirirseniz şunları elde edersiniz:
    • yazmaçlar->start[0] için 0, yazmaçlar->end[0] için 2
    • yazmaçlar->start[1] için 0, yazmaçlar->end[1] için 2
    • yazmaçlar->start[2] için 0, yazmaçlar->end[2] için 1
    • yazmaçlar->start[3] için 1, yazmaçlar->end[3] için 2
  • Şayet bir grup bir kereden fazla eşleşiyorsa (ardından bir yineleme işleci geliyor olabilir), işlev son eşleşen grup hakkındaki bilgileri raporlar.
    Örneğin, (a)* ifadesini aa dizgesi ile eşleştirirseniz şunları elde edersiniz:
    • yazmaçlar->start[0] için 0, yazmaçlar->end[0] için 2
    • yazmaçlar->start[1] için 1, yazmaçlar->end[1] için 2
  • Şayet i'inci grup başarılı bir eşleşmede yer almamış ise (örneğin; kullanılmamış bir VEYA işleci veya sıfır kere tekrarlamaya ayarlı bir yineleme işleci olabilir), işlev yazmaçlar->start[1] ve yazmaçlar->end[1] için -1 atar.
    Örneğin, (a)*b ifadesini b dizgesi ile eşleştirirseniz şunları elde edersiniz:
    • yazmaçlar->start[0] için 0, yazmaçlar->end[0] için 1
    • yazmaçlar->start[1] için -1, yazmaçlar->end[1] için -1
  • Şayet i'inci grup sıfır uzunluktaki bir dizge ile eşleşirse, işlev yazmaçlar->start[0] ve, yazmaçlar->end[0] alanlarını sıfır uzunluktaki dizgenin hemen sonrasındaki indise ayarlar.
    Örneğin, (a*)b ifadesini b dizgesi ile eşleştirirseniz şunları elde edersiniz:
    • yazmaçlar->start[0] için 0, yazmaçlar->end[0] için 1
    • yazmaçlar->start[0] için 0, yazmaçlar->end[0] için 0
  • Şayet i'inci grup, grup içindeki başka bir grup tarafından ihtiva edilmeyen bir j'inci gruba sahipse ve işlev i'inci grubun eşleşmesini rapor ediyorsa, j'inci grubun son eşleşmesi (şayet böyle bir eşleşme olmuş ise) yazmaçlar->start[j] ve yazmaçlar->end[j] içine kaydedilir.
    Örneğin, ((a*)b)* ifadesi abb dizgesi ile ve 2. grup bir boş dizge ile eşleşirse, evvelce yapılan eşleşme ne ise onu elde etmiş oluruz:
    • yazmaçlar->start[0] için 0, yazmaçlar->end[0] için 3
    • yazmaçlar->start[1] için 2, yazmaçlar->end[1] için 3
    • yazmaçlar->start[2] için 2, yazmaçlar->end[2] için 2
    ((a)*b)* ifadesi abb dizgesi ile ve son eşleşmede 2. grup eşleşmezse, şunları elde ederiz:
    • yazmaçlar->start[0] için 0, yazmaçlar->end[0] için 3
    • yazmaçlar->start[1] için 2, yazmaçlar->end[1] için 3
    • yazmaçlar->start[2] için 0, yazmaçlar->end[2] için 1
  • Şayet i'inci grup, grup içindeki başka bir grup tarafından ihtiva edilmeyen bir j'inci gruba sahipse ve işlev yazmaçlar->start[i] ve yazmaçlar->end[i] alanların -1'e ayarlamışsa, yazmaçlar->start[j] ve yazmaçlar->end[j] alanları da -1'e ayarlanır.
    Örneğin, ((a)*b)*c ifadesini c dizgesi ile eşleştirirseniz şunları elde edersiniz:
    • yazmaçlar->start[0] için 0, yazmaçlar->end[0] için 1
    • yazmaçlar->start[1] için -1, yazmaçlar->end[1] için -1
    • yazmaçlar->start[2] için -1, yazmaçlar->end[2] için -1
Önceki Üst Ana Başlık Sonraki
GNU Çeviri Tabloları Başlangıç GNU Şablon Tamponlarının Serbest Bırakılması
Bir Linux Kitaplığı Sayfası