다음은 제가 응시한 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+
- 단어에서 하나 이상의 문자(2개 및 3개)와 일치합니다.[ \t]*
- 0개 이상의 공백이나 탭\([ \t]*int
- 여는 대괄호((
) 뒤에 0개 이상의 공백이나 탭이 오고 그 뒤에 문자열이 옵니다.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
여기에서 위의 실제 일치 항목의 빨간색 부분을 볼 수 있습니다 .