Coding/C,C++

Regex in c++

수업을 진행하면서 c++에서 처음으로 regex를 사용해보았는데 거의 반나절을 삽질한 내용을 포스팅 하려고한다.

진행은 하나 예시를 들어 진행한다.

Example

예시는 다음과 같이 http data가 있다고 할 떄 Host:이후에 있는 데이터를 뽑아내려고 할 때 로 가정한다.

GET / HTTP/1.1Host: test.gilgil.netConnection: keep-aliveUpgrade-Insecure-Requests: 
1User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) 
Chrome/81.0.4044.138 Safari/537.36Accept: text/html,application/xhtml+xml,application/xml;q=0.9,
image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9Accept-Encoding: gzip, 
deflateAccept-Language: ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7

데이터를 뽑아낼 떄 정규표현식은 다음과 같이 표현할 수 있다.

"Host: (.*)"
정규표현식 연습은 https://regex101.com/ 와 같은 온라인 사이트를 이용하면 편하다

 

https://regex101.com/ 사이트를 통해 직접 실험해보면 다음과 같이 Full match는 Host: 가 해당하는 줄이 매칭이 되며, Group1이 우리가 원하는 데이터가 매칭이 되었다는 것을 확인할 수 있다.

https://user-images.githubusercontent.com/62448408/82586053-f2ab3c80-9bd1-11ea-8002-961e2467c4ad.png

그렇다면 직접 코딩을 하여 출력을 해보자

 

TEST Code #1

#include <iostream>
#include <regex>

using namespace std;

int main() {    
	string str="GET / HTTP/1.1\n"\                     
    "Host: test.gilgil.net\n"\                     
    "Connection: keep-alive\n"\                     
    "Upgrade-Insecure-Requests: 1\n"\                     
    "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36\n"\
    "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9\n"\
	"Accept-Encoding: gzip, deflate\n"\                     
	"Accept-Language: ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7\n";    
    
    regex pattern("Host: (.*)");    
    smatch tmp;   
    
    if(regex_match(str,tmp,pattern)){        
    	cout << "regex_match success : " <<tmp[1].str() << endl;    
    }    
    
    if(regex_search(str,tmp,pattern)){        
    	cout << "regex_search success : " <<tmps[1].str() << endl;    
    }    
    return 0;
}

TEST Code #1을 간단하게 설명을 하자면

먼저 str에는 http 데이터를 Text형태로 넣어주었다

regex pattern에는 정규 표현식을 넣어주었으며, 매칭된 후 매칭된 문자열을 저장할 tmp를 선언하였다.

그리고 regex_match와 regex_search 두 함수를 사용하였는데 이는 간단하게 두 함수를 비교를 하기 위하여 사용해주었다.

두 함수 인자에는 검색할 문자열, 매칭된 내용을 저장할 smatch 변수, 정규표현식이 저장된 regex 순으로 넣어준다.

참고로 tmp[0]에는 full match된 문자열이 들어가있으며, tmp[1]에는 첫번쨰 Group이 들어간다 이를 .str()을 사용해주면 string 형태로 반환해준다 .length 등 여러가지가 있으니 알아보면 좋다.

 

실행 결과는 다음과 같다.

결과를 보면 regex_search함수에서 매칭이 되어서 출력된것을 확인할 수 있다.

여기서 regex_match와 regex_search의 차이를 알 수 있다.

regex_match는 완벽하게 일치하는 매칭일때만 true를 반환하고 search는 부분적이여도 매칭을 해준다.

 

TEST Code #2

#include <iostream>
#include <regex>

using namespace std;

int main(){    
	const char packet[] = "\x47\x45\x54\x20\x2f\x20\x48\x54\x54\x50\x2f\x31\x2e\x31\x0d\x0a" \
    "\x48\x6f\x73\x74\x3a\x20\x74\x65\x73\x74\x2e\x67\x69\x6c\x67\x69" \
    "\x6c\x2e\x6e\x65\x74\x0d\x0a\x43\x6f\x6e\x6e\x65\x63\x74\x69\x6f" \
    "\x6e\x3a\x20\x6b\x65\x65\x70\x2d\x61\x6c\x69\x76\x65\x0d\x0a\x55" \
    "\x70\x67\x72\x61\x64\x65\x2d\x49\x6e\x73\x65\x63\x75\x72\x65\x2d" \
    "\x52\x65\x71\x75\x65\x73\x74\x73\x3a\x20\x31\x0d\x0a";    
    
    regex pattern1("Host: .*");    
    regex pattern2("\x48\x6f\x73\x74\x3a\x20(.*)");    
    cmatch tmp;    
    string str(packet);    
    smatch stmp    
    if(regex_search(packet,tmp,pattern1)){        
    	cout << "pattern1 is success : " <<tmp[1].str() << endl;    
    }    
    
    if(regex_search(str,stmp,pattern2)){        
    	cout << "pattern2 is success : " <<stmp[1].str() << endl;    
    }    
    
    return 0;
}

TEST Code #2는 실제 패킷이 잡혔다는 가정으로 진행을 한다.

먼저 packet 배열에는 실제 http 데이터의 일부분을 넣어주었다.

그리고 pattern을 두가지를 만들었다. 하나는 이전과 같은 패턴이며, 다른 하나는 Host:를 hex값으로 표현을 한 것이다. 그리고 cmatch와 smacth 두가지를 선언해주었는데, 이는 regex_search에서 문자열을 string으로 넘길건지 char * 형으로 넘길건지 에 따라 cmatch인지 smatch인지 차이가 있다.

실행결과는 다음과 같다.

https://user-images.githubusercontent.com/62448408/82608740-2f892a80-9bf6-11ea-9466-cac4a9c73d3f.png

pattern1이나 pattern2나 char *이나 string 형이나 차이없이 같은 결과가 나온것을 확인할 수 있다.

 

Reference

'Coding > C,C++' 카테고리의 다른 글

백준 2941  (0) 2019.12.26
백준 10828  (0) 2019.12.24
백준 10773  (0) 2019.12.24