以下是我参加的 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 程序员)。
- A。
grep -E "int[ \t]+\w+[ \t]*\([ \t]*int" *.c
- B.
grep -E "^int\w+[A-Za-z_]+\w*\(\w*int" *.c
- C。
grep -E "int.+\([ \t]+int.*\) " *.c
- D .
grep -E "int[ \t]+[A-Za-z_][ \t]+\(int" *.c
参考:http://gnosis.cx/publish/programming/exam101.html- 特别是这个问题 - 1.3/7/1。
答案1
假设当您参加测试时,您实际上无法grep
针对输入数据运行命令,那么您将不得不查看表达式并进行一些猜测。
以相反的顺序查看它们:
D .
grep -E "int[ \t]+[A-Za-z_][ \t]+\(int" *.c
这不允许函数名称长于单个字符 ( ),并假定函数名称和参数列表之间
[A-Za-z_]
至少必须有空格、反斜杠或空格。t
匹配
int a (int
或int at(int
但不匹配int foo(int
。C。
grep -E "int.+\([ \t]+int.*\) " *.c
这假设参数列表至少以一个空格、反斜杠或 开头
t
。匹配
int foo( int
或int foo(tint
但不匹配int foo(int
。B.
grep -E "^int\w+[A-Za-z_]+\w*\(\w*int" *.c
这不允许
int
返回类型和函数名称之间有任何空格,并且假定函数定义从行的开头开始(示例代码包含一些缩进的函数定义)。匹配
intfoo(int
但不匹配int foo(int
。A。
grep -E "int[ \t]+\w+[ \t]*\([ \t]*int" *.c
这是唯一允许匹配 的函数
int foo(int
,但它也匹配无效的函数名称,例如int 000(int
.然而,它是四个给定正则表达式中最好的正则表达式。
还要注意,这个问题假设 GNUgrep
进行匹配\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+
- 这匹配一个单词中的一个或多个字符(两个和三个)[ \t]*
- 零个或多个空格或制表符\([ \t]*int
- 左括号 ((
) 后跟零个或多个空格或制表符,后跟字符串int
笔记:该问题假设 GNU,grep
因为它使用\w
.的其他实现grep
不支持使用正则表达式 ( -E
) 来表示这种表示法,对于这些实现,使用[[:alnum:]]
是更好的选择。另外一个更明智的选择是替代[[:blank:]]
,[ \t]
因为从技术上讲,它匹配空格、反斜杠和 t,正如 POSIX 所要求的那样。
重写“A”。回答这是一个更合规的解决方案:
$ grep -E "int[[:blank:]]+[[:alpha:]_][[:alnum:]_]+[[:blank:]]*\([[:blank:]]*int" sample.c
在这里您可以看到上面grep
实际匹配的红色部分: