Language/C++

[C++] 정규 표현식 with C++

nowkoes 2023. 8. 6. 00:00

regex

개요

 정규 표현식(Regualar Expreesion)문자열을 검색하거나 대체하는 데 사용되는 패턴이다. 이 패턴은 고정된 문자열이 될 수도 있고, 복잡한 문자열 패턴을 설명하는 규칙이 될 수도 있다. 이러한 표현식은 다양한 프로그래밍 언어에서 사용되며, C++에서는 regex 라이브러리를 사용하여 정규 표현식을 처리할 수 있다.

 

 정규 표현식은 다음과 같은 경우에 유용하다.

 

  • 특정 패턴을 가진 문자열을 찾을 때
  • 문자열을 분리하거나 대체할 때
  • 데이터 유효성 검사

 

 이번 시간에는 regex 라이브러리를 활용해서 문자열을 분석하고 조작하는 다양한 방법들에 대해 알아보자. 


본문

 먼저 정규 표현식에 나오는 문법들에 대해 간단하게 알아보자. 여기서는 일반적으로 사용되는 몇 가지 기본적인 문법에 대해서만 설명하겠다.

 

  • .: 임의의 한 문자를 나타낸다. 예를 들어, a.c는 "abc", "a9c", "a#c" 등과 일치한다.
  • *: 앞의 요소가 0번 이상 반복됨을 나타낸다. 예를 들어, a*는 "", "a", "aa", "aaa" 등과 일치한다.
  • +: 앞의 요소가 1번 이상 반복됨을 나타낸다. 예를 들어, a+는 "a", "aa", "aaa" 등과 일치하며, ""와는 일치하지 않는다.
  • ?: 앞의 요소가 0번 또는 1번 나타남을 나타낸다. 예를 들어, a?는 "", "a"와 일치한다.
  • \\d: 숫자를 나타낸다. \\d는 "0"에서 "9"까지의 어떤 숫자와도 일치한다.
  • \\w: "word character"를 나타낸다. \\w는 알파벳, 숫자, 밑줄 (_)과 일치한다.
  • \\s: 공백 문자를 나타낸다. \\s는 탭, 캐리지 리턴, 줄 바꿈, 공백 등과 일치한다.
  • \\b: 단어 경계를 나타낸다. \\b는 단어의 시작과 끝을 구분한다.
  • [...]: 대괄호 안의 어떤 문자와도 일치한다. 예를 들어, [abc]는 "a", "b", "c"와 일치한다.
  • [^...]: 대괄호 안의 문자를 제외한 어떤 문자와도 일치한다. 예를 들어, [^abc]는 "a", "b", "c"를 제외한 모든 문자와 일치한다.
  • ^: 문자열 또는 줄의 시작을 나타낸다. 예를 들어, ^a는 "a"로 시작하는 문자열과 일치한다.
  • $: 문자열 또는 줄의 끝을 나타낸다. 예를 들어, a$는 "a"로 끝나는 문자열과 일치한다.

 

 이러한 조합들을 이용하여 다음과 같이 표현할 수도 있다. 예를 들어, (100+1+ | 01)+ 라는 패턴이 있다고 가정해 보자. 이를 세분화해 보면

 

  • 100+: 100 뒤에 0이 하나 이상 나오는 문자열
  • 1+: 1이 하나 이상 나오는 문자열
  • 100+1+: 100뒤에 0이 하나 이상 있고, 그 뒤에 1이 하나 이상 있는 문자열
  • 01: 01 문자열 패턴
  • 100+1+ | 01: 100+1+ 패턴이나 01 패턴 중 하나
  • (100+1+ | 01)+: 위 패턴이 하나 이상 반복되는 문자열

 

 이렇게 나눌 수 있다. 이를 이용하여 3자리 국가코드, 4자리 중간 번호, 4자리 마지막 번호를 나타내는 휴대폰 번호를 찾기 위한 정규 표현식을 나타내면 다음과 같다. \\b010-\\d{4}-\\d{4}\\b

 

  • \\b: 휴대폰 번호는 010-과 같이 단어의 시작을 나타냄. 이는 010-이 다른 숫자 또는 문자에 의해 중간에 끼여있지 않음을 보장
  • 010: 문자열 010을 의미
  • -: 문자 -을 의미
  • \\d{4}: 4자리의 숫자를 의미
  • -: 문자 -을 의미
  • \\d{4}" 4자리의 숫자를 의미
  • \\b: 단어의 끝을 의미

 

출처: cppreference

 

 C++ 공식 문서에 나와 있는 regex library 설명 문서다. 간단하게 regex정규 표현식을 처리하며, 정규 표현식 객체를 나타내거나, 정규 표현식에 의해 생성된 결과를 저장하는 등의 기능을 제공한다. 이를 이용하여 위의 전화번호를 찾는 매칭 함수를 만들어 보자.


예제

전화번호 매칭

#include <iostream>
#include <regex>
#include <string>
using namespace std;

bool matching(const string& number) 
{
    regex e("\\b010-\\d{4}-\\d{4}\\b");
    return std::regex_match(number, e);
}

int main()
{
    string input;
    cout << "입력: ";
    cin >> input;

    if (matching(input))
        cout << "주어진 입력은 휴대폰 번호의 형식과 일치합니다.\n";

    else
        cout << "주어진 입력은 휴대폰 번호의 형식과 일치하지 않습니다.\n";
}

출력 결과

 

 입력으로 주어진 문자열 input이 매칭되었는지 확인하는 코드다. 

 

문자열 검색

#include <regex>
#include <string>
#include <iostream>
using namespace std;

int main() 
{
    string input;
    cout << "문장 입력: ";
    getline(cin, input);
    
    regex e("\\b\\w+\\b"); 
    regex_iterator<string::iterator> rit(input.begin(), input.end(), e);
    regex_iterator<string::iterator> rend;

    while (rit != rend) 
    {
        std::cout << rit->str() << std::endl;
        ++rit;
    }

    return 0;
}

출력 결과

 

 입력으로 주어진 문자열 input에서 단어를 출력하는 코드다. 

 

문자열 대체

#include <regex>
#include <string>
#include <iostream>
using namespace std;

int main() 
{
    string input, tmp;
    cout << "문장 입력: ";
    getline(cin, input);
    
    cout << "단어를 대체할 문자 입력: ";
    cin >> tmp;

    regex e("\\b\\w+\\b");
    string result;

    regex_replace(back_inserter(result), input.begin(), input.end(), e, tmp);
    cout << result;

    return 0;
}

출력 결과

 

 입력으로 주어진 문자열 input에서 단어를 특정 문자열로 대체하는 코드다.


요약

regex
1. 정의: 문자열을 검색하거나 대체하는 데 사용되는 패턴
2. 기능
 a. regex_match: 주어진 문자열 전체가 정규 표현식과 일치하는지 확인하고, 결과를 bool 값으로 반환
 b. regex_search: 문자열 내에서 정규 표현식과 일치하는 부분이 있는지 확인하고, 결과를 bool 값으로 반환. 또한, 검색된 부분의 위치와 내용을 얻을 수 있음
 c. regex_replace: 문자열 내에서 정규 표현식과 일치하는 부분을 다른 문자열로 대체
3. 문법
 - 특별한 메타 문자( '.', '*', '?', '+')들을 사용하여 문자열 패턴을 만들 수 있음
반응형