2014-11-03 5 views
0

이것은 이전의 SO 질문과 그 토론의 연속입니다. 내 SO 질문에 C에서 정규 표현식 "그룹화"를 여러 정규 표현식에 사용 하시겠습니까?

Different Between std::regex_match & std::regex_search

는 다음과 같은 정규 표현식은 지정된 입력 문자열에서 가져 오기 위해 작성되었습니다 :

std::string input{ "Mon Nov 25 20:54:36 2013" }; 
//Day:: Exactly Two Number surrounded by spaces in both side 
std::regex r{R"(\s\d{2}\s)"}; 

대답 중 하나, 그것은에 R"(.*?\s(\d{2})\s.*)"로 변경되었습니다 생성하여 그룹 및 첫 번째 하위 일치를 캡처합니다. regex_match 또는 regex_search을 사용하여 하루 정보를 파싱하는 데 모두 잘 작동합니다.

std::string input{ "Mon Nov 25 20:54:36 2013" }; 


    //DayStr:: Exactly Three Letter at the start and followed by spaces(Output: Mon) 
    std::regex dayStrPattern{ R"(^\w{3}\s)" }; 
    //Day:: Exactly Two Number surrounded by spaces in both side(Output: 25) 
    std::regex dayPattern{ R"(\s\d{2}\s)" }; 
    //Month:: Exactly Three letter surrounded by spaces in both side(Output: Nov) 
    std::regex monthPattern{ R"(\s\w{3}\s)" }; 
    //Year:: Exactly Four Number at the end of the string(Output: 2013) 
    std::regex yearPattern{ R"(\s\d{4}$)" }; 
    //Hour:: Exactly two Number surrounded by spaces in left side and : in right side(Output:20) 
    std::regex hourPattern{ R"(\s\d{2}:{1})" }; 
    //Min:: Exactly two Number sorruounded by : in left side and : in right side(Output: 54) 
    std::regex minPattern{ R"(:{1}\d{2}:{1})" }; 
    //Second::Exactly two Number surrounded by : in the left side and space in right side(Output: 36) 
    std::regex secPattern{ R"(:{1}\d{2}\s)" }; 

나는 위의 정규식 here을 테스트 한 그들은 올바른 것 같다 다음과 같이

는 지금은 위의 입력 문자열에서 다양한 일을 구문 분석하려면 다음 regex expressions을 썼다. 우리는 방법 std::regex_search 대신 7 가지 정규식 단일 정규식 표현 을 통과 할 수 있도록

이제 우리는 여기에 그룹화 메커니즘을 사용할 수 있습니다.?. 이렇게하면 std :: regex_search는 출력을 std::smatch 하위 일치 벡터에 저장합니다. 여기는 가능합니까? 나는 documentation와 A Tour Of C++ book를 읽었지 만, regular expression grouping에 대해 많이 이해하지 못했습니다.

일반적으로/std :: regex_search의 한 호출에서 다양한 정보를 얻을 수 있도록/디자인 그룹화를 사용해야하는시기와 방법은 무엇입니까? 나는 표준 7 번 호출해야 할이 시점 :: regex_search 공히 다른 정규식 식에서

다양한 정보를 가져오고 그것을 사용합니다. 나는 내가 지금하고있는 것보다 그것을 달성하는 더 좋은 방법이 있다고 확신한다.

+0

에 단일 통화 후 match_results을 통해 얻을 수 변경 데이트 필드? 그러한 가정이 없다면 현재의 방법이 단일 정규식 솔루션보다 낫을 수도 있습니다. – nhahtdh

+0

@nhahtdh : 그렇습니다. 주문은 이렇게 할 수 있습니다. 여기에있는 주요 아이디어는 (이 예제뿐만 아니라) 정규식에서 그룹화를 사용하는 방법을 이해하는 것입니다. –

+0

질문에 오류가 있습니다. 캡처 그룹을 만들기 위해'\ d {2}'주위에 괄호를 추가 할 것을 제안했습니다. 따라서 답안에서 '정규식'은'R '(. *? \ s (\ d {2}) \ s. *) "'(여분의 괄호에 주목하십시오)입니다. 예제 코드에 정의 된 캡처 그룹이 없습니다. – Praetorian

답변

2

regex_match을 7 번 입력하여 동일한 입력에 일치시킬 필요없이 매번 하나씩이 아닌 여러 캡처 그룹을 만들면됩니다. 예를 들어, regex

std::regex r{R"(^(\w{3}) (\w{3}) (\d{2}) (\d{2}):(\d{2}):(\d{2}) (\d{4})$)"}; 

그리고 우리의 순서에 대한 가정을 만들 수 다음 모든 일치 regex_match

if (std::regex_match(input,match,r)){ 
    for(auto const& m : match) { 
     std::cout << m << '\n'; 
    } 
} 

Live demo

+0

그룹화하는 순서는 입력과 동기화되어야합니까?이 개념에 대해 조금 더 설명해 주시겠습니까? –

+1

@MantoshKumar 예, 입력 된 필드는 항상 표시된 순서대로 있어야합니다. 또한 한 자리 날짜 및 시간을 처리하기 위해 숫자 캡처를'(\ d {1,2}) '로 변경할 수 있습니다 (예 : 한 달의 첫 번째 입력에 0이 채워지지 않은 경우). – Praetorian

+0

@MantoshKumar 당신이 찾고있는 설명이 확실하지 않습니다. 입력에서 7 개의 필드를 추출하려고 했으므로 각각에 대해 7 개의 캡처 그룹을 만들었습니다. 0 번째 요소는 항상 전체 일치이기 때문에 8 개의 match_results 출력이 있습니다. 나머지 (1-7)는'regex'에서 캡쳐 그룹과 같은 순서로 입력 문자열의 필드입니다. – Praetorian