[C++] 정규표현식(regex)

yeolife ㅣ 2023. 7. 7. 09:15

정의

#include <regex>

정규표현식으로 문자열을 다양하게 다룰 수 있다.

  • 문자열의 규칙을 확인
  • 문자열의 패턴을 검색
  • 문자열의 패턴을 치환

 

regex_match

전체 문자열이 정규표현식에 일치하는지 검사한다

  • 전체 문자열이 정규표현식에 일치하면 True, 일치하지 않으면 False를 반환
// 정규표현식을 만족하면 0 또는 1 반환
bool check_str(string str, regex re) {
	if(regex_match(str, re))
    		return true;
    
	return false;
}
입력 출력
변수 함수 반환
str "asd123@naver.com" True
re // 이메일 정규표현식
regex(R"(([\w]*)(@)([\w\.]*))")

 

  • 정규표현식에 만족하는 전체 문자열을 부분적으로 파싱하기
    • 정규표현식의 소괄호 () 에 따라 구분함
vector<string> ans; // 결과 저장

void parsing_str(string str, regex re) {
	int i = 0;
	smatch mat;

	regex_match(str, mat, re);

	while(mat[i].str() != "") {
		ans.push_back(mat[i].str());
        	i++;
	}
}
입력 출력
변수 변수
str "asd123@naver.com" // mat[0].str()
mat.str()
"asd123@naver.com"
mat[1].str() "asd123"
re // 이메일 정규표현식
regex(R"(([\w]*)(@)([\w\.]*))")
mat[2].str() "@"
mat[3].str() "naver.com"

 

regex_search

정규표현식에 일치하는 부분 문자열을 검색한다

  • 전체 문자열 중에 정규표현식에 일치하는 가장 가까운 부분 문자열을 검색하기
vector<string> ans; // 결과 저장

void search_str(string str, regex re) {
	smatch mat;

	regex_search(str, mat, re);
	
    // 이전 문자열
	ans.push_back(mat.prefix());
    
    // 일치 문자열
    ans.push_back(mat.str());
    
    // 남은 문자열
    ans.push_back(mat.suffix());
}
입력 출력
변수 변수
str R"(asd123@naver.com
qwe123@daum.net
zxc123@google.com)"
// 이전 문자열
mat.prefix()
""
// 일치 문자열
mat.str()
"asd123@naver.com"
re // 이메일 정규표현식
regex(R"(([\w]*)(@)([\w\.]*))")
// 이후 문자열
mat.suffix()
"qwe123@daum.net
zxc123@google.com"

 

  • 정규표현식에 일치하는 모든 부분 문자열을 검색하기
vector<string> ans; // 결과 저장

void search_str_all(string str, regex re) {
	smatch mat;

	while(regex_search(str, mat, re)) {
    		ans.push_back(mat.str());
        	str = mat.suffix();
	}
}
입력 출력
변수 변수
str R"(asd123@naver.com
qwe123@daum.net
zxc123@google.com)"
// 1번째 while
mat.str()
"asd123@naver.com"
// 2번째 while
mat.str()
"qwe123@daum.net"
re // 이메일 정규표현식
regex(R"(([\w]*)(@)([\w\.]*))")
// 3번째 while
mat.str()
"zxc123@google.com"

 

regex_iterator

regex_search와 같이 정규표현식에 일치하는 모든 부분 문자열 검색한다.

vector<string> ans; // 결과 저장

void search_str_all(string str, regex re) {
    auto st = sregex_iterator(str.begin(), str.end(), re);
    auto en = sregex_iterator();
    
    while (st != en) {
    		ans.push_back(st -> str());
        	++st;
    }
}

 

regex_replace

정규표현식에 일치하는 부분 문자열을 다른 문자열로 치환한다.

  • 정규표현식에 일치하는 부분 문자열을 치환하기
string replace_str(string str1, string str2, regex re) {
	string ans = regex_replace(str1, re, str2); // str1 -> str2
    
    return ans;
}
입력 출력
변수 변수
str1 // 변경할 문자열
"asd123@naver.com"
ans "zxc123@naver.com"
str2 // 변경될 문자열
"zxc123"
re regex(R"(asd123)")

 

  • 캡쳐 그룹으로 정규표현식에 일치하는 문자열의 위치를 교환하기
    • 정규표현식의 소괄호 () 에 따라 캡쳐 그룹을 구분
string replace_str(string str, regex re, int idx1, int idx2) {
    string capture1 = "$" + to_string(idx1);
   	string capture2 = "$" + to_string(idx2);
    
    // 캡쳐 1과 캡쳐 2의 자리를 바꿈
    string capture3 = capture2 + "@" + capture1; 
	
    string ans = regex_replace(str, re, capture3);
    
    return ans;
}
입력 출력
변수 변수
str // 변경할 문자열
"asd123@naver.com"
ans "naver.com@asd123"
re // 1번째 캡쳐 = ([\w]*)
// 2번째 캡쳐 = (@) 
// 3번째 캡쳐 = ([\w\.]*)
regex(R"(([\w]*)(@)([\w\.]*))")
idx1 1
idx2 3

참고 글 - 모두의 코드 (정규 표현식)