정규표현식
정규 표현식(regular expression, regex)은 특정한 규칙을 가진 문자열의 패턴을 표현하는 방법입니다. 정규 표현식은 문자열 검색, 일치, 치환 등을 수행하는 데 사용됩니다. 프로그래밍 언어와 텍스트 편집기에서 자주 사용되며, 데이터 검증, 텍스트 파싱, 데이터 변환 등의 작업에 유용합니다.
기본 개념
- 리터럴 문자: 문자 그대로 일치하는 문자열을 찾습니다.
- 예: abc는 "abc" 문자열과 일치합니다.
- 메타 문자: 특별한 의미를 가진 문자들로, 패턴 매칭을 제어합니다.
- .: 임의의 한 문자와 일치 (줄 바꿈 문자는 제외)
- ^: 문자열의 시작과 일치
- $: 문자열의 끝과 일치
- *: 0회 이상 반복
- +: 1회 이상 반복
- ?: 0회 또는 1회 일치
- |: OR 연산자 (선택)
- 문자 클래스: 대괄호 [] 안에 포함된 문자 중 하나와 일치
- [abc]: 'a', 'b', 'c' 중 하나와 일치
- [a-z]: 'a'부터 'z'까지의 모든 문자와 일치
- [^abc]: 'a', 'b', 'c'를 제외한 모든 문자와 일치
- 수량자: 앞의 요소가 나타나는 횟수를 지정
- {n}: 정확히 n번 일치
- {n,}: 최소 n번 일치
- {n,m}: n번 이상, m번 이하 일치
- 그룹과 캡처: 소괄호 ()를 사용하여 부분 문자열을 그룹화하고 캡처
- (abc): 'abc'와 일치하고, 이를 캡처 그룹으로 저장
- (?:abc): 'abc'와 일치하지만, 캡처하지 않음
- 역참조: 이전에 캡처된 그룹을 재참조
- \1, \2 등: 첫 번째, 두 번째 캡처 그룹을 재참조
- 이스케이프 시퀀스: 메타 문자를 일반 문자로 사용하기 위해 \를 사용
- \.: '.' 문자 자체와 일치
- \\: '' 문자 자체와 일치
C++ 에서는 <regex> 헤더파일을 통해 사용이 가능하다.
1. std::regex_search
std::regex_search는 문자열 내에서 정규 표현식과 일치하는 부분을 검색합니다.
#include <iostream>
#include <regex>
#include <string>
int main() {
std::string text = "My email is example@example.com.";
std::regex email_pattern(R"([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})");
std::smatch match;
if (std::regex_search(text, match, email_pattern)) {
std::cout << "Email found: " << match[0] << std::endl;
} else {
std::cout << "No email found." << std::endl;
}
return 0;
}
2. std::regex_match
std::regex_match는 문자열이 정규 표현식과 완전히 일치하는지 확인합니다.
#include <iostream>
#include <regex>
#include <string>
int main() {
std::string email = "example@example.com";
std::regex email_pattern(R"([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})");
if (std::regex_match(email, email_pattern)) {
std::cout << "Valid email address." << std::endl;
} else {
std::cout << "Invalid email address." << std::endl;
}
return 0;
}
3. std::regex_replace
std::regex_replace는 문자열에서 정규 표현식과 일치하는 부분을 다른 문자열로 치환합니다.
#include <iostream>
#include <regex>
#include <string>
int main() {
std::string text = "I have a cat. I love my cat.";
std::regex cat_pattern(R"(\bcat\b)");
std::string replacement = "dog";
std::string result = std::regex_replace(text, cat_pattern, replacement);
std::cout << "Original: " << text << std::endl;
std::cout << "Modified: " << result << std::endl;
return 0;
}
다음과 같이 함수를 사용할 수 있으며
마지막으로 정규표현식에 익숙해질수 있도록 예제문제 몇가지를 올려본다.
(더보기를 누르면 답과 해석을 볼 수 있습니다.)
예제 문제 1: 이메일 주소 검증
문제: 이메일 주소가 올바른 형식인지 확인하는 정규 표현식을 작성하세요. 이메일 주소는 다음 조건을 만족해야 합니다:
- 알파벳 소문자, 대문자, 숫자, 점(.), 밑줄(_), 더하기(+), 하이픈(-) 문자를 포함할 수 있습니다.
- "@" 문자를 포함해야 합니다.
- "@" 문자 이후에 알파벳 소문자, 대문자, 숫자, 점(.), 하이픈(-)이 올 수 있습니다.
- 마지막 부분은 최소 두 글자 이상의 알파벳 소문자, 대문자여야 합니다.
^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$
- ^: 문자열의 시작을 의미합니다.
- [a-zA-Z0-9._%+-]+: 알파벳 대소문자, 숫자, 점(.), 밑줄(_), 퍼센트(%), 더하기(+), 하이픈(-) 중 하나 이상이 올 수 있습니다.
- @: '@' 문자입니다.
- [a-zA-Z0-9.-]+: 알파벳 대소문자, 숫자, 점(.), 하이픈(-) 중 하나 이상이 올 수 있습니다.
- \.: 점(.) 문자입니다.
- [a-zA-Z]{2,}: 알파벳 대소문자가 최소 2개 이상 와야 합니다.
- $: 문자열의 끝을 의미합니다.
예제 문제 2: 전화번호 검증
문제: 미국 전화번호가 올바른 형식인지 확인하는 정규 표현식을 작성하세요. 전화번호는 다음 형식을 가져야 합니다:
- 3자리 숫자와 이어지는 "-" 또는 "." 문자
- 3자리 숫자와 이어지는 "-" 또는 "." 문자
- 4자리 숫자
^\d{3}[-.]\d{3}[-.]\d{4}$
- ^: 문자열의 시작을 의미합니다.
- \d{3}: 숫자(\d) 3자리입니다.
- [-.]: 하이픈(-) 또는 점(.) 중 하나입니다.
- \d{3}: 숫자 3자리입니다.
- [-.]: 하이픈(-) 또는 점(.) 중 하나입니다.
- \d{4}: 숫자 4자리입니다.
- $: 문자열의 끝을 의미합니다.
예제 문제 3: URL 검증
문제: URL이 올바른 형식인지 확인하는 정규 표현식을 작성하세요. URL은 다음 조건을 만족해야 합니다:
- "http://" 또는 "https://"로 시작해야 합니다.
- 도메인은 알파벳 소문자, 대문자, 숫자, 점(.)을 포함할 수 있습니다.
- 도메인 이름 이후에 선택적으로 슬래시(/)와 추가 경로가 올 수 있습니다.
- ^: 문자열의 시작을 의미합니다.
- https?: 'http' 또는 'https'입니다. 's'는 선택적입니다.
- :\/\/: '://' 문자열입니다.
- [a-zA-Z0-9.-]+: 알파벳 대소문자, 숫자, 점(.), 하이픈(-) 중 하나 이상이 올 수 있습니다.
- \/?: 슬래시(/)는 선택적입니다.
- $: 문자열의 끝을 의미합니다.
예제 문제 4: 날짜 검증
문제: 날짜가 "YYYY-MM-DD" 형식인지 확인하는 정규 표현식을 작성하세요. 날짜는 다음 조건을 만족해야 합니다:
- 연도는 4자리 숫자여야 합니다.
- 월은 01부터 12까지의 2자리 숫자여야 합니다.
- 일은 01부터 31까지의 2자리 숫자여야 합니다.
^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$
- ^: 문자열의 시작을 의미합니다.
- \d{4}: 숫자 4자리입니다.
- -: 하이픈(-) 문자입니다.
- (0[1-9]|1[0-2]): 01에서 09 또는 10에서 12 사이의 2자리 숫자입니다.
- -: 하이픈(-) 문자입니다.
- (0[1-9]|[12]\d|3[01]): 01에서 09, 10에서 29, 30 또는 31 사이의 2자리 숫자입니다.
- $: 문자열의 끝을 의미합니다.
예제 문제 5: 비밀번호 검증
문제: 비밀번호가 올바른 형식인지 확인하는 정규 표현식을 작성하세요. 비밀번호는 다음 조건을 만족해야 합니다:
- 최소 8자 이상이어야 합니다.
- 적어도 하나의 소문자, 하나의 대문자, 하나의 숫자, 하나의 특수 문자를 포함해야 합니다.
^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$
- ^: 문자열의 시작을 의미합니다.
- (?=.*[a-z]): 최소 하나의 소문자(a-z)를 포함해야 합니다.
- (?=.*[A-Z]): 최소 하나의 대문자(A-Z)를 포함해야 합니다.
- (?=.*\d): 최소 하나의 숫자(0-9)를 포함해야 합니다.
- (?=.*[@$!%*?&]): 최소 하나의 특수 문자(@, $, !, %, *, ?, &)를 포함해야 합니다.
- [A-Za-z\d@$!%*?&]{8,}: 알파벳 대소문자, 숫자, 특수 문자 중 8자 이상으로 구성됩니다.
- $: 문자열의 끝을 의미합니다.
예제 문제 6: IPv4 주소 검증
문제: IPv4 주소가 올바른 형식인지 확인하는 정규 표현식을 작성하세요. IPv4 주소는 다음 조건을 만족해야 합니다:
- 4개의 숫자로 구성되어 있으며, 각 숫자는 0부터 255까지입니다.
- 각 숫자는 점(.)으로 구분됩니다.
^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$
- ^: 문자열의 시작을 의미합니다.
- (25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?): 0에서 255 사이의 숫자를 의미합니다. 세부적으로:
- 25[0-5]: 250에서 255 사이의 숫자
- 2[0-4][0-9]: 200에서 249 사이의 숫자
- [01]?[0-9][0-9]?: 0에서 199 사이의 숫자
- \.: 점(.) 문자입니다. 이 패턴이 4번 반복됩니다.
- $: 문자열의 끝을 의미합니다.
'개발 지식' 카테고리의 다른 글
테스트에 관한 짧은 글 (0) | 2024.08.07 |
---|---|
게임에서의 내적 (0) | 2024.07.29 |
Git 협업을 위한 Branch 정리 (1) | 2024.02.27 |
비트 연산 (0) | 2023.07.28 |
코드 디버깅(debugging) (1) | 2023.07.19 |