2014-01-08 3 views
1

C++에서 regexes를 사용하여 특정 단어와 일치하는 줄을 다른 두 패턴으로 묶인 파일의 영역 내에서 추출하려고합니다. 나는 또한 각 경기의 라인 번호를 인쇄하고 싶다.다른 두 패턴 사이의 일치하는 줄 추출

나는 현재 popen를 사용하여 perl 명령을 실행하고,하지만 난 C++와 함께 할 싶습니다 :

perl -ne 'if ((/START/ .. /END/) && /test/) {print "line$.:$_"}' file 

이 명령은 단어 test를 포함하는 추출물 라인에서 STARTEND 다음 사이의 지역을 찾습니다.

C에서 정규 표현식을 사용하여 이것을 어떻게합니까?

+0

당신이 http://www.cplusplus.com/reference/regex/ 봤어? –

+0

나는 줄 번호를 얻는 방법을 모른다. –

+1

그럴 경우, 질문에 지금까지 가지고있는 C++을 추가하십시오. (또는 지금 어떻게 작성해야 할지를 적어 두십시오.) 그러면 훨씬 쉽게 응답 할 것입니다. –

답변

3

semantics of Perl’s ..은 미묘합니다. 아래 코드는 ..while (<>) { ... }을 모두 에뮬레이트하여 -n 스위치를 perl으로 변경합니다.

#include <fstream> 
#include <iostream> 
#include <regex> 
#include <vector> 

// emulate Perl's .. operator 
void flipflop(bool& inside, const std::regex& start, const std::regex& end, const std::string& str) 
{ 
    if (!inside && std::regex_match(str, start)) 
    inside = true; 
    else if (inside && std::regex_match(str, end)) 
    inside = false; 
} 

int main(int argc, char *argv[]) 
{ 
    // extra .* wrappers to use regex_match in order to work around 
    // problems with regex_search in GNU libstdc++ 
    std::regex start(".*START.*"), end(".*END.*"), match(".*test.*"); 

    for (const auto& path : std::vector<std::string>(argv + 1, argv + argc)) { 
    std::ifstream in(path); 
    std::string str; 
    bool inside = false; 
    int line = 0; 
    while (std::getline(in, str)) { 
     ++line; 
     flipflop(inside, start, end, str); 
     if (inside && std::regex_match(str, match)) 
     std::cout << path << ':' << line << ": " << str << '\n'; 

     // Perl's .. becomes false AFTER the rhs goes false, 
     // so keep this last to allow match to succeed on the 
     // same line as end 
     flipflop(inside, start, end, str); 
    } 
    } 

    return 0; 
} 

예를 들어, 다음 입력을 고려하십시오.

test ERROR 1 
START 
test 
END 
test ERROR 2 
START 
foo ERROR 3 
bar ERROR 4 
test 1 
baz ERROR 5 
END 
test ERROR 6 
START sldkfjsdflkjsdflk 
test 2 
END 
lksdjfdslkfj 
START 
dslfkjs 
sdflksj 
test 3 
END dslkfjdsf

샘플 실행 :

$ ./extract.exe file 
file:3: test 
file:9: test 1 
file:14: test 2 
file:20: test 3 

$ ./extract.exe file file 
file:3: test 
file:9: test 1 
file:14: test 2 
file:20: test 3 
file:3: test 
file:9: test 1 
file:14: test 2 
file:20: test 3
관련 문제