개념과 사용 방법
PHP에서 사용하는 정규 표현식(Regular Expression)의 기본 개념과 주요 함수, 활용 방법을 살펴봅니다.
정규 표현식(Regular Expression)이란?
문자열을 다루다 보면 문자열에서 특정 규칙이나 패턴을 찾아내거나 검사해야 할 일이 아주 많습니다.
예를 들면, 다음과 같은 경우입니다.
- 문자열이 이메일 형식(예:
account@example.com)에 맞는지 검사할 때 - 문자열이 숫자만으로 구성되었는지, 영문자만으로 구성되었는지 검사할 때
- 사용자로부터 받은 비밀번호 문자열이 영문 대소문자, 숫자, 특수문자를 혼합했는지 규칙을 검사할 때
- 채팅창이나 댓글에서 특정 욕설, 단어 등의 패턴을 찾아 차단해야 할 때
이런 예처럼, 문자열에서 정해진 규칙이나 패턴을 가진 문자열의 집합을 표현하는 형식을 정규 표현식(Regular Expression)이라고 합니다.
정규 표현식을 사용하면 문자열에서 특정 규칙이나 패턴을 찾거나 검사할 때 매우 유용합니다.
정규 표현식이 PHP에서만 사용되는 것은 아닙니다. 자바스크립트, 펄, 루비, 파이썬, C, C++ 등 대부분의 프로그래밍 언어에서 문자열의 규칙이나 패턴을 찾거나 검색할 때 사용하고 있습니다.
정규 표현식은 여러 문법 체계가 있지만, PHP에서는 가장 대중적이며, 강력한 문법 체계를 가진 정규 표현식을 가지고 있는 프로그래밍 언어인 펄(Perl)의 정규 표현식 체계를 사용합니다. 그래서 PHP의 정규 표현식을 PCRE(Perl Compatible Regular Expressions, Perl 호환 정규 표현식)이라고 말합니다. 많은 PHP 개발자들은 PHP의 정규 표현식을 단순히 PCRE이라고만 축약해서 부르는 경우가 많으니 참고하세요.
PHP 정규 표현식 기본 구조
PHP에서 정규 표현식을 사용할 때 가장 먼저 마주하는 것은 독특한 코드 생김새입니다.
PHP의 정규 표현식의 기본 구조는 '구분자패턴구분자플래그' 형태로 이루어진 하나의 문자열입니다.
정규식을 사용할 때는 반드시 이 구조를 갖추어야 합니다.
'/^[0-9]+$/i'
│ │ ││
│ │ │└─ 플래그(Flag 또는 Modifier): 대소문자 무시 등 옵션 (선택)
│ │ └──── 구분자(Delimiter): 패턴의 시작과 끝을 알림 (필수)
│ └────────── 패턴(Pattern): 찾고자 하는 규칙 (필수)
└──────────────── 구분자(Delimiter): 패턴의 시작과 끝을 알림 (필수)
하나의 문자열
PHP에서 정규 표현식은 하나의 문자열이어야 합니다.
홑따옴표(') 또는 쌍따옴표(")를 사용해 문자열을 표기하면 됩니다.
아래는 홑따옴표(')를 사용한 예입니다.
'/^[0-9]+$/i'
쌍따옴표(")를 사용할 수도 있습니다.
"/^[0-9]+$/i"
구분자(Delimiter)
필수. 패턴의 시작과 끝을 감싸는 기호입니다. 알파벳, 숫자, 백슬래시(\)를 제외한 임의의 특수문자를 쓸 수 있습니다.
구분자(Delimiter)
가장 흔한 형태: 슬래시(/)를 주로 씁니다.
'/^[0-9]+$/i'
- 가장 흔한 형태: 슬래시(
/)를 주로 씁니다. (예:/^[0-9]+$/) - 다른 기호 사용 가능: 패턴 내부에 슬래시가 많이 들어간다면(예: URL 주소), 가독성을 위해
#이나~를 써도 됩니다. (예:/^[0-9]+$/➔#^[0-9]+$#)
구분자(Delimiter)
다른 기호 사용 가능: 알파벳, 숫자, 백슬래시(\)를 제외한 임의의 특수문자를 쓸 수 있습니다.
'#^[0-9]+$#i'
패턴(Pattern)
필수. 실제 찾고자 하는 문자열의 패턴을 정규식 문법으로 작성하는 핵심 부분입니다.
패턴에는 찾고자 하는 문자열, 문자열 규칙 등이 올 수 있습니다. 문자열 자체를 표현하려면 문자열 자체를 작성하면 되고, 문자열 규칙을 표현하려면 문자 자체로는 일반 문자와 다르게 특정한 패턴 방식으로 해석되는 메타 문자(Meta-characters)를 포함해서 작성합니다.
패턴(Pattern)
'/^[0-9]+$/i'
^: 문자열의 시작을 의미하는 메타 문자입니다.[0-9]: 0부터 9까지의 숫자 중 하나와 일치하는 문자 집합을 표현합니다.+: 앞의 규칙([0-9])이 1번 이상 반복됨을 의미하는 메타 문자입니다 (즉, 빈 문자열은 허용하지 않고 최소 1자리 이상의 숫자가 있어야 함).$: 문자열의 끝을 의미하는 메타 문자입니다.
플래그(Flag 또는 Modifier)
옵션. 패턴(Pattern)의 옵션을 설정할 수 있습니다. 일반적으로 '플래그(Flag)'라고 부르지만, PHP 정규 표현식에서는 공식적으로는 '수정자(Modifier)'라고 합니다.
플래그(Flag 또는 Modifier)
'/^[0-9]+$/i'
i: 대소문자 구분 없음 옵션이지만, 이패턴(Pattern) 안에는 알파벳이 없으므로 실질적인 영향은 없습니다.
패턴(Pattern)
필수. 실제 찾고자 하는 문자열의 패턴을 정규 표현식 문법으로 작성하는 핵심 부분입니다. 검색 대상 문자열이 어떤 규칙을 따라야 하는지를 정의합니다.
- 찾고자 하는 문자열 자체만 작성할 수도 있습니다. 이때, 찾으려는 문자열 자체를 작성하면 됩니다.
- 문자열 규칙을 표현하려면 일반 문자와 다르게 특별한 의미로 해석되는 메타 문자를 포함해서 작성합니다.
- 특정 문자 범위를 지정하려면 대괄호(
[]) 안에 특정 문자에 해당하는 패턴을 작성합니다.
찾고자 하는 문자열 자체 표현
'/hello/'
'/hello/'와 같이 작성하면, 대상 문자열 안에서 hello라는 문자열이 포함되어 있는지를 검사하는 가장 단순한 형태의 패턴이 됩니다.
다음의 문자열은 '/hello/'으로 찾을 수 있습니다.
'hello' // 전체 문자열이 hello와 일치
'hello word' // 문자열 앞부분에 포함
'say hello to me' // 문자열 중간에 포함
다음의 문자열은 '/hello/'으로 찾을 수 없습니다.
'Hello' // 대문자 H이므로 실패
'hell' // 글자가 완성되지 않음
'he llo' // 중간에 공백이 있음
메타 문자(Meta-characters)로 규칙 표현
정규 표현식의 강력한 기능은 패턴 안에 다양한 규칙과 의미를 표현할 수 있다는 데 있습니다. 이러한 규칙은 메타 문자를 사용하여 패턴에 표현할 수 있습니다. 메타 문자는 일반 문자처럼 문자 자체를 의미하지 않고, 정규 표현식 문법에 따라 특별한 의미로 해석되는 문자입니다.
패턴(Pattern)에서 메타 문자로 규칙 표현
'/^[0-9]$/'
^: 문자열의 시작을 의미하는 메타 문자입니다.[0-9]: 0부터 9까지의 숫자 중 하나와 일치하는 문자 집합을 표현합니다.$: 문자열의 끝을 의미하는 메타 문자입니다.
다음의 문자열은 '/^[0-9]$/'로 찾을 수 있습니다.
'5' // 일치
'0' // 일치
다음의 문자열은 '/^[0-9]$/'로 찾을 수 없습니다.
'12345' // 불일치([0-9]는 숫자 하나만 허용)
'12a' // 불일치
'a12' // 불일치
주요 메타 문자
다음의 표는 PHP에서 많이 다루는 주요 메타 문자입니다.
^ |
^ 다음에 나오는 문자열로 시작해야 합니다.
(예: ^hello라는 패턴이 있다면 hello로 시작해야 하는 문자열이어야 합니다.) |
|---|---|
$ |
$ 이전에 나오는 문자열로 끝나야 합니다.
(예: hello$라는 패턴이 있다면 hello로 끝나야 하는 문자열이어야 합니다.) |
[ ] |
[ ] 대괄호 안의 문자 중 하나만이라도 일치하면 됩니다.
(예: [abc]라는 패턴이 있다면 문자열에서 a, b, c 중 하나만이라도 일치하면 됩니다.) |
- |
-는 문자열의 범위를 지정합니다. 연속된 숫자나 알파벳의 처음과 끝을 지정해 줄 수 있습니다.
(예: 0-9라는 패턴은 0에서 9까지의 숫자 범위를 지정하며, A-Z라는 패턴은 A에서 Z까지의 대문자의 범위를, a-z라는 패턴은 a에서 z까지의 소문자의 범위를 지정합니다.) |
+ |
+는 앞 문자열 패턴이 최소 한 번은 등장해야 일치합니다.
(예: abc+라는 패턴은 ab 뒤에 c가 최소 한 번 이상 나와야 합니다. [abc]+라는 패턴은 대괄호 안의 글자(a, b, c) 중 아무 글자나 조합해서 최소 한 번 이상 나와야 합니다.) |
[ ] 대괄호 메타 문자로 많이 활용되는 문자 범위
대괄호([ ]) 안에서는 하이픈(-)을 사용해 문자 범위(Character Range)를 지정할 수 있습니다. 다음은 실무에서 자주 사용하는 대표적인 문자 범위 표현입니다.
[0-9] |
0부터 9까지의 숫자 중 하나 |
|---|---|
[a-z] |
a부터 z까지의 영문 소문자 중 하나 |
[A-Z] |
A부터 Z까지의 영문 대문자 중 하나 |
[a-zA-Z] |
영문 대소문자 중 하나 |
[a-zA-Z0-9] |
영문 대소문자와 숫자 중 하나 |
참고: 추가 메타 문자
주요 메타 문자 이외에도 PHP에서 사용할 수 있는 메타 문자들은 많습니다. php.net의 Meta-characters를 참고하시기 바랍니다.
플래그(Flag 또는 Modifier)
정규 표현식에서 플래그는 작성한 패턴(Pattern)을 어떤 방식으로 처리할지 지정하는 옵션입니다. 플래그는 정규 표현식 문자열의 마지막 구분자(Delimiter) 뒤에 작성하며, 필요하지 않은 경우 생략할 수 있습니다.
일반적으로 '플래그(Flag)'라고 부르지만, PHP 정규 표현식에서는 공식적으로는 '수정자(Modifier)'라고 합니다.
플래그(Flag 또는 Modifier)
'/hello/i'
위 예시처럼 i 플래그를 사용하면 영문 대소문자를 구분하지 않고 패턴을 검사합니다.
'hello' // 일치
'Hello' // 일치
'HELLO' // 일치
자주 사용하는 플래그
다음의 표는 PHP에서 자주 사용하는 플래그입니다.
i |
영문 대소문자를 구분하지 않습니다. (Case-insensitive) |
|---|---|
m |
여러 줄 문자열에서 ^와 $가 각 줄의 시작과 끝을 인식하게 합니다. (Multiline) |
u |
패턴과 대상 문자열을 UTF-8 모드로 처리하도록 지정합니다. 한글과 같은 멀티바이트 문자를 올바르게 처리할 때 사용합니다. (Unicode) |
플래그는 여러 개를 동시에 사용할 수도
래그는 여러 개를 동시에 사용할 수도 있습니다. 예를 들어 '/hello/iu'라고 작성하면 대소문자를 구분하지 않으면서 유니코드까지 지원하는 정규식이 됩니다.
참고: 추가 플래그
자주 사용하는 플래그 이외에도 PHP에서 사용할 수 있는 플래그는 더 있습니다. php.net의 Internal option setting를 참고하시기 바랍니다.
정규 표현식의 주요 함수와 활용 방법
PHP에서는 정규 표현식을 직접 처리하는 전용 내장 함수들을 제공합니다. 이 함수들은 모두 PCRE(Perl Compatible Regular Expressions) 기반으로 동작하며, 문자열 검색, 검사, 추출, 교체 등 다양한 작업에 활용할 수 있습니다.
주요 정규 표현식 함수
PHP에서 많이 사용하는 주요 정규 표현식 함수입니다.
preg_match()
|
주어진 정규 표현식 패턴을 사용하여 문자열 내에서 일치(match)하는 부분을 찾아냅니다. |
|---|---|
preg_match_all()
|
정규 표현식을 사용하여 주어진 문자열에서 일치하는 모든 부분을 찾아 그 결과를 반환합니다. |
preg_replace()
|
문자열 내에서 정규 표현식을 사용하여 특정 패턴을 찾아 다른 문자열로 바꾸는(교체하는, 치환) 함수입니다. |
preg_split()
|
문자열을 주어진 정규 표현식 패턴을 기준으로 나누어 배열로 변환하여 반환합니다. 이 함수는 특히 정규 표현식을 활용한 문자열 분리, URL 분석 등의 작업에서 유용하게 사용됩니다. |
preg_match()
다음은 preg_match() 함수를 사용해서 주어진 문자열에서 정규 표현식 패턴과 일치하는 부분이 있는지 검사하는 예제입니다.
$text = 'Hello PHP';
if (preg_match('/PHP/', $text)) {
echo "찾았습니다.";
}
// 출력: 찾았습니다.
preg_match_all()
다음은 preg_match_all() 함수를 사용해서 주어진 문자열에서 정규 표현식 패턴과 일치하는 모든 부분을 찾는 예제입니다.
$text = 'apple banana apple';
preg_match_all('/apple/', $text, $matches);
print_r($matches[0]);
/* 출력:
Array
(
[0] => apple
[1] => apple
)
*/
preg_replace()
다음은 preg_replace() 함수를 사용해서 정규 표현식 패턴과 일치하는 문자열을 다른 문자열로 교체하는 예제입니다.
$input = '안녕하세요, PHP!';
$pattern = '/안녕하세요/'; // '안녕하세요'를 찾는 정규 표현식
$replacement = '안녕'; // '안녕하세요'를 '안녕'으로 교체
$output = preg_replace($pattern, $replacement, $input);
echo "Original input: $input"; // 출력: "Original input: 안녕하세요, PHP!"
echo "Output: $output"; // 출력: "Output: 안녕, PHP!"
preg_split()
다음은 preg_split()함수를 사용해서 정규 표현식 패턴을 기준으로 문자열을 나누는 예제입니다.
/* URL에서 프로토콜 종류를 분리하는 간단한 예시 */
$url = "https://www.example.com/path/to/resource";
$parts_url = preg_split('#://#', $url);
print_r($parts_url);
/* 출력:
Array (
[0] => https
[1] => www.example.com/path/to/resource
)
*/
echo '프로토콜의 종류: ' . $parts_url[0]; // 출력: '프로토콜의 종류: https'