grepに関するテスト質問

grepに関するテスト質問

以下は、私が受験したLPIC-1練習試験の試験問題です。正解はAです。私は何が起こっているのか本当に混乱しています。あまり難しいことでなければ、Aが正解なのか教えてくれる人はいますか?

int double(int n)
    { /* int arg, int return */
       return n*2;
    }
    char hello(int n)
    { /* int arg, char return */
       printf("hello %i\n", n);
    }
    int five()
    { /* no args, int return */
       return 5;
    }
    int        triple(int n, int other, char nonsense)
    { /* int arg, int return */
       return n*3;
    }

Cソースファイルを正しく解析するには、洗練されたパーサー(Cコンパイラーに組み込まれたパーサーなど)が必要です。それにもかかわらず、正規表現を使用すると、多くのプログラム構造のおおよその説明を合理的に提供できます。次の検索のうち、intを最初の引数として受け入れ、intを返す(そしてよく偽の肯定を生成しない)、ほとんどのC関数を探す検索は何ですか?この展覧会には、注釈付きの複数の一致関数と不一致関数(非Cプログラマー用)を含むCコードの断片が含まれています。

  • ㅏ。grep -E "int[ \t]+\w+[ \t]*\([ \t]*int" *.c
  • 雨。grep -E "^int\w+[A-Za-z_]+\w*\(\w*int" *.c
  • 氏。grep -E "int.+\([ \t]+int.*\) " *.c
  • ディ。grep -E "int[ \t]+[A-Za-z_][ \t]+\(int" *.c

引用:http://gnosis.cx/publish/programming/exam101.html- 特にこの質問は - 1.3/7/1。

答え1

テストするときに実際にgrep入力データに対してコマンドを実行できないと仮定すると、式を見ていくつかの推測が必要です。

逆順で確認してください。

  • ディ。grep -E "int[ \t]+[A-Za-z_][ \t]+\(int" *.c

    これは、関数名が単一文字()より長くなることを許可しません。関数[A-Za-z_]名と引数リストの間に少なくともスペース、バックスラッシュ、またはスペースが必要であると仮定します。t

    一致int a (intまたはint at(int一致しませんint foo(int

  • 氏。grep -E "int.+\([ \t]+int.*\) " *.c

    これは引数リストが少なくとも空白、バックスラッシュ、またはt

    一致int foo( intまたはint foo(tint一致しませんint foo(int

  • 雨。grep -E "^int\w+[A-Za-z_]+\w*\(\w*int" *.c

    これは戻り値の型と関数名の間にスペースを入れず、int関数定義が行の先頭から始まると仮定します(例コードにはインデントされた関数定義が含まれています)。

    一致intfoo(intが一致しませんint foo(int

  • ㅏ。grep -E "int[ \t]+\w+[ \t]*\([ \t]*int" *.c

    これは一致を許可する唯一の関数ですが、int foo(int無効な関数名とも一致します。int 000(intたとえば、与えられた4つの正規表現の中で最高の正規表現です。

また、この質問ではgrep一致のためにGNUを想定しています\w。標準grep実装を使用することをお勧めします。[[:alnum:]_]スペースまたはタブ(スペース、バックスラッシュ、または一致)を一致させる代わりに使用する必要があります。\w[[:blank:]][ \t]t

答え2

だから「A」。サンプルコードで定義された2つの関数を返す唯一の関数であるため、答えです。

$ grep -E "int[ \t]+\w+[ \t]*\([ \t]*int" sample.c
int double(int n)
    int        triple(int n, int other, char nonsense)

残りの3つは試しても結果は返されません。これが機能する理由は、次の行に表示される両方の状況を処理するためです。

int double(int n)
    int        triple(int n, int other, char nonsense)

これgrep

  • int[ \t]+- 次の文字で始まり、intその後に少なくとも1つのスペースまたはタブ(\t)が続く行と一致します。
  • \w+- 単語内の1つ以上の文字(2つと3つ)と一致します。
  • [ \t]*- 0個以上のスペースまたはタブ
  • \([ \t]*int- 開く角かっこ(()の後にゼロ個以上のスペースやタブが続き、その後に文字列が続きます。int

メモ:この質問では、regex()を使用する他の実装はこの表記法をサポートせず、regex()を使用する実装がより良いオプションなので、grepGNUを想定しています。もう一つの合理的な選択は代替です。これは、技術的にはPOSIXが要求するように空白、バックスラッシュ、およびtと一致するためです。\wgrep-E[[:alnum:]][[:blank:]][ \t]

「A」を書き換えます。回答これは、より規制に準拠するソリューションです。

$ grep -E "int[[:blank:]]+[[:alpha:]_][[:alnum:]_]+[[:blank:]]*\([[:blank:]]*int" sample.c

grepここで上記の実際の一致の赤い部分を見ることができます。

SS2

関連情報