2010-11-19 13 views
4

Cで素早くUTF-8文字列から句読点をフィルタリングする必要があります。現在使用している関数は非常に非効率的です: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; 
} 

ご覧のとおり、各句読記号の文字列を繰り返します。すべての句読点に対してこれを効率的に完了できる単純なライブラリ関数はありますか?

+0

どのコンパイラを使用していますか? (gccは正規表現モジュールを提供しています)また、Cの正規表現を検索して、可能性の詳細なリストを入手してください。 – KevinDTimm

+1

正直なところ、私は自分自身に失望しています。私はしばらくのうちにCを毎日使っていないし、ispunctはずっと良い選択です。私は、単純なものがきれいになると不必要に肥大化したメソッドに依存していることに私が前向きにコメントしています。 – KevinDTimm

答えて

9

より効率的なアルゴリズムは次のとおりです。

#include <ctype.h> 

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

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

    return mystring; 
} 

それはしかしUTF-8固有のものではない - それは現在のロケールが何であれです。 (オリジナルはUTF-8固有ではありませんでした)。

ispunct()char *に置き換えて、句読点のような(潜在的にマルチバイトの)UTF-8文字で始まるかどうかを判断することができます*inの代わりにinとしてください)。

+1

+1。あなたのコードはUTF-8テキストでうまく動作しますが、ispunct()によって認識された7ビットのASCIIページにある句読点だけを削除します。それはUTF-8の素晴らしい機能です。もちろん、OPが実際にギリシャ語、ロシア語、韓国語、タイ語の句読点を捉える必要がある場合は、UTF-8でコード化された実際のUnicodeコードポイントを処理する必要があります。 – RBerteig

+0

これはとてもきれいに簡潔です:) +1 – KeatsKelleher

+0

小さな問題が見つかりました。ループ終了後に文字列にヌルターミネータを追加する必要があります。 * out = '\ 0'; – KeatsKelleher

1

ICUライブラリにはCバインディングがあり、ユニコード\pPの句読点を正しく処理するregexライブラリが含まれています。

関連する問題