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+- 단어에서 하나 이상의 문자(2개 및 3개)와 일치합니다.
  • [ \t]*- 0개 이상의 공백이나 탭
  • \([ \t]*int- 여는 대괄호( () 뒤에 0개 이상의 공백이나 탭이 오고 그 뒤에 문자열이 옵니다.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

관련 정보