2012-01-04 5 views
7

こんにちは私は標準正規表現ライブラリ(regcomp、regexec ..)を使用しています。しかし、今私は正規表現のためのコードにユニコードサポートを追加する必要があります。POSIX regex.hはunicodeまたは基本的に非ASCII文字を提供しますか?

標準正規表現ライブラリは、ユニコードまたは基本的に非ASCII文字を提供しますか?私はウェブを研究し、そうではないと思う。

私のプロジェクトはリソース評論家です。したがって、私はそれに大きなライブラリ(ICUとBoost.Regex)を使いたくありません。

すべてのヘルプは、基本的には...

+1

私が知っているわけではありませんが、計画9の正規表現ライブラリはあります。 Unixポートはhttp://swtch.com/plan9port/unix/にあります。「libregexp9」 – Dave

答えて

6

POSIX RegexがUTF-8ロケールで正しく動作しているように見えます。私はちょうど簡単なテスト(下記参照)を書いて、正規表現"[[:alpha:]]"(例えば)に対してキリル文字と文字列を一致させるために使用しました。そしてすべてうまく動作します。

注:あなたが覚えておかなければならない主なこと - 正規表現関数はロケールに関連しています。その前にsetlocale()に電話する必要があります。

#include <sys/types.h> 
#include <string.h> 
#include <regex.h> 
#include <stdio.h> 
#include <locale.h> 

int main(int argc, char** argv) { 
    int ret; 
    regex_t reg; 
    regmatch_t matches[10]; 

    if (argc != 3) { 
    fprintf(stderr, "Usage: %s regex string\n", argv[0]); 
    return 1; 
    } 

    setlocale(LC_ALL, ""); /* Use system locale instead of default "C" */ 

    if ((ret = regcomp(&reg, argv[1], 0)) != 0) { 
    char buf[256]; 
    regerror(ret, &reg, buf, sizeof(buf)); 
    fprintf(stderr, "regcomp() error (%d): %s\n", ret, buf); 
    return 1; 
    } 

    if ((ret = regexec(&reg, argv[2], 10, matches, 0)) == 0) { 
    int i; 
    char buf[256]; 
    int size; 
    for (i = 0; i < sizeof(matches)/sizeof(regmatch_t); i++) { 
     if (matches[i].rm_so == -1) break; 
     size = matches[i].rm_eo - matches[i].rm_so; 
     if (size >= sizeof(buf)) { 
     fprintf(stderr, "match (%d-%d) is too long (%d)\n", 
       matches[i].rm_so, matches[i].rm_eo, size); 
     continue; 
     } 
     buf[size] = '\0'; 
     printf("%d: %d-%d: '%s'\n", i, matches[i].rm_so, matches[i].rm_eo, 
      strncpy(buf, argv[2] + matches[i].rm_so, size)); 

    } 
    } 

    return 0; 
} 

使用例:UTF-8でキリル文字があまりかかるため

$ locale 
LANG=ru_RU.UTF-8 
LC_CTYPE="ru_RU.UTF-8" 
LC_COLLATE="ru_RU.UTF-8" 
... (skip) 
LC_ALL= 
$ ./reg '[[:alpha:]]' ' 359 фыва' 
0: 5-7: 'ф' 
$ 

マッチング結果の長さが2バイトです。

+0

私はあなたが私を誤解していると思います。私はそれをしたい:./reg 'ç' 'çilek45' – iyasar

+0

それでは何が問題?上のコードはあなたのパラメータと '0:0-2: 'ç'を出力します。つまり、動作します。 –

+0

申し訳ありませんが私のミスそれはありがとう作品... – iyasar

6

をいただければ幸いです、POSIXの正規表現は認識してユニコードではありません。 Unicode文字でそれらを使用しようとすることはできますが、Unicode対応ライブラリが扱う複数のエンコーディングやその他の問題があるグリフには問題がある可能性があります。標準から

IEEE Std 1003.1-2008

マッチングは、文字を符号化するために使用されるビットパターンではなく、文字のグラフィック表現に基づくものでなければなりません。つまり、文字セットにグラフィックシンボルの2つ以上のエンコーディングが含まれている場合、または検索された文字列に複数のコードセットでエンコードされたテキストが含まれている場合、エンコードされたシンボルの他の表現を検索する試みはありません。これが必要な場合、ユーザーは目的のグラフィックシンボルのすべてのバリエーションを含む等価クラスを指定できます。

libpcreはあなたのために働くでしょうか? POSIXの正規表現よりもやや重いですが、ICUやBoostより軽いと思います。

0

実際に「標準」を意味する場合は、std::regex(C++ 11)から、std::wregex(もちろんstd::wstring)に切り替えるだけです。

+0

彼らはPOSIX標準で指定されているregex.hシステムインターフェースについて話しています – Spookbuster

関連する問題