2010-11-19 19 views
4

Noktalı işaretlemeyi UTF-8 dizelerinden C cinsinden hızlı bir şekilde filtrelemem gerekiyor. Dizeler uzun olabilir ve çok fazla olabilir. Şu anda kullanarak işlev çok verimsiz görünmektedir:Noktalama işaretlemenin en hızlı yolu C

char *filter(char *mystring){ 
    char *p; 
    while ((p = strchr(mystring,'.')) != NULL) 
     strcpy(p, p+1); 
    while ((p = strchr(mystring,',')) != NULL) 
     ...etc etc etc... 
    ...etc... 
    return mystring; 
} 

bunu her noktalama işareti dize dolaşır görebileceğiniz gibi. Tüm noktalama işaretleri için bunu verimli bir şekilde tamamlayabilen basit bir kütüphane işlevi var mı?

+0

Hangi derleyiciyi kullanıyorsunuz? (gcc bir regex modülü de sunuyor), 'c' regex için arama olasılıkları oldukça detaylı bir liste – KevinDTimm

+1

almak için dürüst, kendimi hayal kırıklığına uğradım (kendini flagellation başlar). Bir süredir günlük olarak C kullanmıyorum ve ispunct çok daha iyi bir seçim. Basit bir şeyler oldukça güzelce yapılacağı zaman gereksiz yere şişirilmiş yöntemlere güvenmem için bir önceki yorumumu bırakıyorum. – KevinDTimm

cevap

9

Daha verimli algoritmadır:

#include <ctype.h> 

char *filter(char *mystring) 
{ 
    char *in = mystring; 
    char *out = mystring; 

    do { 
     if (!ispunct(*in)) 
      *out++ = *in; 
    } while (*in++); 

    return mystring; 
} 

olsa UTF-8 özgü değil - geçerli yerel neyse bu. (Orijinaliniz UTF-8'e özgü değildi).

bunu UTF-8 yapmak istiyorsanız bir (potansiyel olarak multi-byte) ile başlıyorsa, bir char * alıp belirleyecek bir işlevle ispunct() yerini alabilecek noktalama işareti çeşit UTF-8 karakter (ve *in yerine in ile arayın.

+1

+1. Kodunuz, UTF-8 metni üzerinde mutlu bir şekilde çalışır, ancak 7 bitlik ASCII sayfasında bulunan ispunct() 'tarafından tanınan noktalama işaretlerini kaldırır. Bu UTF-8'in güzel bir özelliği. Elbette OP'nin Yunanca, Rusça, Korece ve Taylandca noktalama işaretlerini yakalaması gerekiyorsa, UTF-8'de kodlanmış gerçek unicode kod noktaları ile uğraşmak zorundadırlar. – RBerteig

+0

bu çok güzel özlü :) +1 – KeatsKelleher

+0

bir küçük sorun bulundu. Döngü tamamlanmadan önce dize eklenmiş boş sonlandırıcıya ihtiyaç var: * out = '\ 0'; – KeatsKelleher

1

ICU kitaplıklarında C bağlamaları vardır ve Unicode \pP noktalama işaretlerini doğru şekilde işleyen bir regex kitaplığı içerir.

İlgili konular