2012-06-05 6 views
8

다음은 "Hut"출력으로 "Hut"을 출력합니다. 나는 그것을 알고있다. * 욕심이 많지만 일치해야하고 그것은 캡쳐 그룹 바깥에있다. 그래서 내 서브 매치에서 왜 그런가?C++ 정규식을 이해하지 못함

#include <string> 
#include <regex> 
#include <iostream> 

using namespace std; 

int main() { 
     regex my_r(".*>(.*)"); 
     string temp(R"~(cols="64">Hut)~"); 
     smatch m; 
     if (regex_match(temp, m, my_r)) { 
       cout << m[1] << endl; 
     } 
} 
+0

정규 표현식 구현은 gcc와 MSVC에서 여전히 매우 낮습니다. – inf

+0

감사합니다. gcc 4.6.3을 사용하고 있습니다. –

+0

g ++ 4.7로 업그레이드했지만 여전히 동일한 출력. 나는 여전히 이것이 정규 표현식에 대한 오해라고 생각한다. 너무 자주 나는 과거의 실수로 소프트웨어를 비난했다. –

답변

7

이것은 libstdC++의 구현 버그입니다. 이보기 :

#include <string> 
#include <regex> 
#include <boost/regex.hpp> 
#include <iostream> 

int main() { 
    { 
     using namespace std; 
     regex my_r("(.*)(6)(.*)"); 
     smatch m; 
     if (regex_match(std::string{"123456789"}, m, my_r)) { 
      std::cout << m.length(1) << ", " 
         << m.length(2) << ", " 
         << m.length(3) << std::endl; 
     } 
    } 

    { 
     using namespace boost; 
     regex my_r("(.*)(6)(.*)"); 
     smatch m; 
     if (regex_match(std::string{"123456789"}, m, my_r)) { 
      std::cout << m.length(1) << ", " 
         << m.length(2) << ", " 
         << m.length(3) << std::endl; 

     } 
    } 

    return 0; 
} 

당신은 GCC로 컴파일 할 경우

는 첫 번째 (된 libstdc는 ++)이 완전히 잘못된 결과 9, -2, 4와 두 번째 (부스트의 구현) 5, 1, 3을 반환에게 반환을 예상대로 사용하십시오.

clang + libC++로 컴파일하면 코드가 정상적으로 작동합니다.

(http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52719에 설명 된대로이 된 libstdC++의 정규식 구현은, "부분적으로 지원"참고.)

+0

오, 이런, 그건 독특하게 짜증나. 다른 구문 옵션을 선택할 수 있습니까? 내가 ECMA-Script가 아닌 다른 것을 원한다는 것이 아니라 ... 그것이 작동하지 않는다면 ... (부수적으로, 나는 왜 그들이 PCRE와 함께 가지 않았는지 궁금해하기 시작했다). –

+0

그런데 GCC 4.7에는 여전히 버그가 있습니다. –

+0

예제와 설명에 감사드립니다. 그것이 부분적으로 만 지원된다면별로 기대하지 않는 편이 나을 것 같아요. 나는 부스트를 사용하거나 당분간 정규식을 피할 것이다. –

3

당신은 당신의 정규 표현식을 수정할 수 있습니다 일치하는 부품 그룹으로 나누어되도록 :

std::regex my_r("(.*)>(.*)\\).*"); // group1>group2).* 
std::string temp("~(cols=\"64\">Hut)~"); 
std::sregex_iterator reg_it(temp.begin(), temp.end(), my_r); 

if (reg_it->size() > 1) { 
    std::cout 
     << "1: " << reg_it->str(1) << std::endl // group1 match 
     << "2: " << reg_it->str(2) << std::endl; // group2 match 
} 

출력 : 그룹 bracets (/* your regex here */)에 의해 지정되어

1: ~(cols="64" 
2: Hut 

주 당신의 bracet 부분을 만들고 싶어 표현식을 입력하면 \ (\\ 코드)으로 이스케이프 처리해야합니다. 자세한 내용은 Grouping Constructs을 참조하십시오.

이 질문은 또한 당신을 도울 수 : How do I loop through results from std::regex_search?

또한 파일의 시작 부분에 using namespace std;를 사용하지 않는, 그것은 나쁜 습관이다.

+0

당신의 대답과'using namespace std;'에 관한 팁에 감사드립니다. 설명에 감사드립니다! –

관련 문제