Bir Arama ve Değiştirme Örneği
Önceki GNU Regex İşlevleri Sonraki
Bir Arama ve Değiştirme Örneği
Bu örnek, bu kitapçığın özgün kopyasında bulunmamaktadır. Tam bir uygulama örneği olarak yararlı olabileceği düşünülerek bu çeviriye eklenmiştir.
Örnek kodun yaptığı iş bir dizgeyi <b>, </b> ve <i>, </i> etiketlerinden arındırmaktır. İşlemi hızlandırmak için özel bir hızlı eşlem (fastmap) kullanılmıştır. Bu özel fastmap sayesinde eşleşme araması "/<>bi" dizgesindeki karakterlerden birine rastlanığında başlatılacağından işlemin beklenenden daha çabuk biteceği düşünülmüştür. SET_FASTMAP() makrosu bu hızlı eşlem dizisini ilklendirmek içindir.
unformat işlevi argümanı olan string dizgesini bu etiketlerden arındırır ve bunu ek bir tampon kullanmadan doğrudan bu dizge üzerinde yapar. Arama işleminin her yinelenişinde dizge giderek etiketlerden arındığından ve özel bir hızlı eşlem kullanıldığından, dizge içinde aramanın başlatılacağı konumun ilerletilmesine gerek duyulmamıştır.
void
get_regerror(int errcode, re_pattern_buffer *compiled, char *func) {

    size_t length = regerror (errcode, compiled, NULL, 0);
    char *buffer = xmalloc (length);

    regerror (errcode, compiled, buffer, length);
    fprintf(stderr, "%s: %s\n", func, buffer);
    free(buffer);
}

#define SET_FASTMAP() \
{ \
  unsigned this_char; \
  \
  memset (fastmap, invert, (1 << BYTEWIDTH)); \
  \
  for (this_char = 0; this_char < strlen (fastmap_string); this_char++)\
    fastmap[fastmap_string[this_char]] = !invert; \
  fastmap['\n'] = match_newline; \
}

void
unformat (char *string) {
  char *pattern;
  struct re_pattern_buffer compiled;
  char fastmap[1 << BYTEWIDTH];
  const char *comperr;
  char *fastmap_string;
  unsigned invert, match_newline;
  struct re_registers *matches;
  int execerr, len, prelen, postlen, slen;

  re_set_syntax (RE_NO_BK_PARENS | RE_NO_BK_VBAR);
  pattern = "(<.>|</.>)";
  invert = 0;
  match_newline = 0;
  fastmap_string = "/<>bi";
  SET_FASTMAP ();

  memset (&compiled, 0, sizeof (compiled));
  comperr = re_compile_pattern(pattern, strlen(pattern), &compiled);
  if (comperr)
    get_regerror((int)*comperr, &compiled, "re_compile_pattern");

  /* Şablon derlendi. Biçim arıtmasına başlayabiliriz. */
  slen = strlen(string);
  compiled.fastmap = fastmap;
  matches = alloca (sizeof(matches) * (compiled.re_nsub + 1));
  while (1) {
    memset (matches, 0, sizeof (matches));
    execerr = re_search (&compiled, string, slen, 0, slen, matches);
    if (execerr == - 1) {
      /* puts ("Eşleşme bulunamadı"); */
      break;
    }
    if (execerr >= 0) {
      len = matches->end[0] - matches->start[0];
      postlen = slen - matches->end[0];
      prelen = matches->start[0];
      strncpy(string + prelen, string + matches->end[0], postlen);
      slen = prelen + postlen;
      string[slen] = '\0';
    } else {
      get_regerror(comperr, &compiled, "re_search");
    }
  }
}
Önceki Üst Ana Başlık Sonraki
GNU Şablon Tamponlarının Serbest Bırakılması Başlangıç POSIX Regex işlevleri
Bir Linux Kitaplığı Sayfası