以下は、私が受験した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()を使用する実装がより良いオプションなので、grep
GNUを想定しています。もう一つの合理的な選択は代替です。これは、技術的にはPOSIXが要求するように空白、バックスラッシュ、およびtと一致するためです。\w
grep
-E
[[:alnum:]]
[[:blank:]]
[ \t]
「A」を書き換えます。回答これは、より規制に準拠するソリューションです。
$ grep -E "int[[:blank:]]+[[:alpha:]_][[:alnum:]_]+[[:blank:]]*\([[:blank:]]*int" sample.c
grep
ここで上記の実際の一致の赤い部分を見ることができます。