5

Cで変数宣言を認識するための正規表現に取り組んでおり、これを取得しました。

[a-zA-Z_][a-zA-Z0-9]*

より良い解決策はありますか?

4

6 に答える 6

11

C の変数宣言を認識するパターン。従来の宣言を見ると、次のようになります。

int variable;

その場合は、文字列やプリプロセッサで定義された定数など、他のものとの一致を避けるために、何よりも前にtypeキーワードをテストする必要があります。

(?:\w+\s+)([a-zA-Z_][a-zA-Z0-9]+)

変数名は \1 にあります。

必要な機能は、後読み/先読みです。

2015 年 7 月 11 日更新

_前の正規表現では、一部の変数が途中で一致しません でした。これを修正するに_は、最初のキャプチャ グループの 2 番目の部分に を追加するだけで済みます。また、2 つ以上の文字の変数名を想定しています。これは、修正後の外観です。

(?:\w+\s+)([a-zA-Z_][a-zA-Z0-9_]*)

ただし、この正規表現には多くの誤検知goto jump;があり、そのうちの 1 つであり、率直に言って、この仕事には適していません。そのため、より広い範囲のケースをカバーする別の正規表現を作成することにしましたが、完全にはほど遠いですが、ここにあります。 :

\b(?:(?:auto\s*|const\s*|unsigned\s*|signed\s*|register\s*|volatile\s*|static\s*|void\s*|short\s*|long\s*|char\s*|int\s*|float\s*|double\s*|_Bool\s*|complex\s*)+)(?:\s+\*?\*?\s*)([a-zA-Z_][a-zA-Z0-9_]*)\s*[\[;,=)]

Ruby、Python、JavaScript でこの正規表現をテストしましたが、一般的なケースでは非常にうまく機能しますが、失敗する場合もあります。また、いくつかの正規表現エンジン間での移植性を維持しながら最適化を行うことは困難ですが、正規表現にはいくつかの最適化が必要になる場合があります。

テスト再開

unsignedchar *var;                   /* OK, doesn't match */
goto **label;                        /* OK, doesn't match */
int function();                      /* OK, doesn't match */
char **a_pointer_to_a_pointer;       /* OK, matches +a_pointer_to_a_pointer+ */
register unsigned char *variable;    /* OK, matches +variable+ */
long long factorial(int n)           /* OK, matches +n+ */
int main(int argc, int *argv[])      /* OK, matches +argc+ and +argv+ (needs two passes) */
const * char var;                    /* OK, matches +var+, however, it doesn't consider +const *+ as part of the declaration */
int i=0, j=0;                        /* 50%, matches +i+ but it will not match j after the first pass */
int (*functionPtr)(int,int);         /* FAIL, doesn't match (too complex) */

偽陽性

次のケースは、移植可能な正規表現でカバーするのが難しく、テキスト エディターはコンテキストを使用して、引用符内のテキストの強調表示を回避します。

printf("int i=%d", i);               /* FAIL, match i inside quotes */

誤検知 (構文エラー)

これは、正規表現を適用する前にソース ファイルの構文をテストすると修正できます。GCC と Clang を使用すると、 -fsyntax-only フラグを渡すだけで、コンパイルせずにソース ファイルの構文をテストできます。

int char variable;                  /* matches +variable+ */
于 2012-10-21T00:29:16.250 に答える
1

これにより、return および typedef の偽フラグがなくなります。戻り値の型と変数名をキャプチャでき、ポインターと配列をサポートします。また、typedef 変数の検出に加えて、コメント化されたコードを排除し、誤フラグをさらに減らします。

^\s*(?!return |typedef )((\w+\s*\*?\s+)+)+(\w+)(\[\w*\])?(\s*=|;)
于 2016-02-16T18:34:20.227 に答える