[2026] C++ 정규표현식 | regex 완벽 가이드

[2026] C++ 정규표현식 | regex 완벽 가이드

이 글의 핵심

C++ 정규표현식의 핵심 개념과 실무 포인트를 정리합니다.

기본 사용법

아래 코드는 cpp를 사용한 구현 예제입니다. 필요한 모듈을 import하고, 조건문으로 분기 처리를 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#include <regex>
#include <iostream>
using namespace std;
int main() {
    regex pattern("\\d+");  // 숫자 패턴
    
    string text = "abc123def456";
    
    // 검색
    if (regex_search(text, pattern)) {
        cout << "숫자 발견" << endl;
    }
}

아래 코드는 cpp를 사용한 구현 예제입니다. 조건문으로 분기 처리를 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

regex pattern("\\d+");
string s1 = "123";
string s2 = "abc123";
// regex_match: 전체 문자열 매칭
cout << regex_match(s1, pattern) << endl;  // 1 (true)
cout << regex_match(s2, pattern) << endl;  // 0 (false)
// regex_search: 부분 문자열 매칭
cout << regex_search(s1, pattern) << endl;  // 1
cout << regex_search(s2, pattern) << endl;  // 1

캡처 그룹

아래 코드는 cpp를 사용한 구현 예제입니다. 조건문으로 분기 처리를 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

regex pattern("(\\d{3})-(\\d{4})-(\\d{4})");
string phone = "010-1234-5678";
smatch match;
if (regex_match(phone, match, pattern)) {
    cout << "전체: " << match[0] << endl;  // 010-1234-5678
    cout << "지역: " << match[1] << endl;  // 010
    cout << "중간: " << match[2] << endl;  // 1234
    cout << "끝: " << match[3] << endl;    // 5678
}

실전 예시

예시 1: 이메일 검증

아래 코드는 cpp를 사용한 구현 예제입니다. 조건문으로 분기 처리를 수행합니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

bool isValidEmail(const string& email) {
    regex pattern(R"(^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$)");
    return regex_match(email, pattern);
}
int main() {
    cout << isValidEmail("test@example.com") << endl;  // 1
    cout << isValidEmail("invalid.email") << endl;     // 0
}

예시 2: URL 파싱

다음은 cpp를 활용한 상세한 구현 코드입니다. 클래스를 정의하여 데이터와 기능을 캡슐화하며, 조건문으로 분기 처리를 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

struct URL {
    string protocol;
    string host;
    string port;
    string path;
};
URL parseURL(const string& url) {
    regex pattern(R"(^(\w+)://([^:/]+)(?::(\d+))?(/.*)?$)");
    smatch match;
    
    if (regex_match(url, match, pattern)) {
        return {
            match[1],  // protocol
            match[2],  // host
            match[3],  // port
            match[4]   // path
        };
    }
    
    return {};
}
int main() {
    auto url = parseURL("https://example.com:8080/path/to/page");
    
    cout << "프로토콜: " << url.protocol << endl;
    cout << "호스트: " << url.host << endl;
    cout << "포트: " << url.port << endl;
    cout << "경로: " << url.path << endl;
}

예시 3: 문자열 치환

아래 코드는 cpp를 사용한 구현 예제입니다. 필요한 모듈을 import하고. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#include <regex>
int main() {
    string text = "Hello World, Hello C++";
    regex pattern("Hello");
    
    // 모두 치환
    string result = regex_replace(text, pattern, "Hi");
    cout << result << endl;  // Hi World, Hi C++
    
    // 첫 번째만 치환
    result = regex_replace(text, pattern, "Hi", regex_constants::format_first_only);
    cout << result << endl;  // Hi World, Hello C++
}

예시 4: 로그 파싱

다음은 cpp를 활용한 상세한 구현 코드입니다. 클래스를 정의하여 데이터와 기능을 캡슐화하며, 에러 처리를 통해 안정성을 확보합니다, 반복문으로 데이터를 처리합니다, 조건문으로 분기 처리를 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

struct LogEntry {
    string timestamp;
    string level;
    string message;
};
vector<LogEntry> parseLog(const string& log) {
    vector<LogEntry> entries;
    
    regex pattern(R"(\[([\d\-: ]+)\] \[(\w+)\] (.+))");
    
    istringstream iss(log);
    string line;
    
    while (getline(iss, line)) {
        smatch match;
        if (regex_match(line, match, pattern)) {
            entries.push_back({
                match[1],  // timestamp
                match[2],  // level
                match[3]   // message
            });
        }
    }
    
    return entries;
}
int main() {
    string log = R"([2026-03-11 10:30:00] [INFO] 서버 시작
[2026-03-11 10:30:05] [ERROR] 연결 실패
[2026-03-11 10:30:10] [WARN] 재시도 중)";
    
    auto entries = parseLog(log);
    
    for (const auto& entry : entries) {
        cout << entry.timestamp << " | " 
             << entry.level << " | " 
             << entry.message << endl;
    }
}

반복자

아래 코드는 cpp를 사용한 구현 예제입니다. 반복문으로 데이터를 처리합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

// 변수 선언 및 초기화
string text = "abc123def456ghi789";
regex pattern("\\d+");
// 모든 매칭 찾기
sregex_iterator it(text.begin(), text.end(), pattern);
sregex_iterator end;
while (it != end) {
    cout << it->str() << endl;  // 123, 456, 789
    ++it;
}

토큰화

아래 코드는 cpp를 사용한 구현 예제입니다. 반복문으로 데이터를 처리합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

string text = "apple,banana,cherry";
regex delimiter(",");
// 토큰 반복자
sregex_token_iterator it(text.begin(), text.end(), delimiter, -1);
sregex_token_iterator end;
while (it != end) {
    cout << *it << endl;  // apple, banana, cherry
    ++it;
}

자주 발생하는 문제

문제 1: 이스케이프

아래 코드는 cpp를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

// ❌ 잘못된 이스케이프
regex pattern("\d+");  // \d가 이스케이프 안됨
// ✅ 이중 백슬래시
regex pattern("\\d+");
// ✅ Raw 문자열 (권장)
regex pattern(R"(\d+)");

문제 2: 성능

아래 코드는 cpp를 사용한 구현 예제입니다. 반복문으로 데이터를 처리합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

// ❌ 매번 regex 생성
for (const string& text : texts) {
    regex pattern("\\d+");  // 비효율
    regex_search(text, pattern);
}
// ✅ regex 재사용
regex pattern("\\d+");
for (const string& text : texts) {
    regex_search(text, pattern);
}

문제 3: 탐욕적 매칭

아래 코드는 cpp를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

string html = "<div>content</div>";
// ❌ 탐욕적
regex greedy("<.*>");
// 매칭: <div>content</div> (전체)
// ✅ 비탐욕적
regex nonGreedy("<.*?>");
// 매칭: <div>, </div> (각각)

정규표현식 문법

다음은 cpp를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

// 문자 클래스
\d  // 숫자 [0-9]
\w  // 단어 [a-zA-Z0-9_]
\s  // 공백
.   // 모든 문자
// 수량자
*   // 0회 이상
+   // 1회 이상
?   // 0 또는 1회
{n} // 정확히 n회
{n,m}  // n~m회
// 앵커
^   // 시작
$   // 끝
\b  // 단어 경계
// 그룹
()  // 캡처 그룹
(?:)  // 비캡처 그룹

FAQ

Q1: 정규표현식은 언제 사용하나요?

A:

  • 문자열 검증
  • 파싱
  • 검색/치환
  • 데이터 추출

Q2: 성능은?

A: 복잡한 패턴은 느릴 수 있습니다. 간단한 경우 string 메서드가 더 빠릅니다.

Q3: Raw 문자열은?

A: R”(…)”로 백슬래시 이스케이프 불필요.

Q4: ECMAScript vs POSIX?

A: 기본은 ECMAScript. regex_constants로 변경 가능.

Q5: 정규표현식 디버깅은?

A:

  • regex101.com
  • regexr.com
  • 간단한 패턴부터 테스트

Q6: Regex 학습 리소스는?

A:

  • cppreference.com
  • “Mastering Regular Expressions”
  • regex101.com

같이 보면 좋은 글 (내부 링크)

이 주제와 연결되는 다른 글입니다.

관련 글

... 996 lines not shown ... Token usage: 63706/1000000; 936294 remaining Start-Sleep -Seconds 3