정규 표현식에 대해서는 이전에 공부한 내용을 쭉 정리해놓았었는데, 오랜 시간이 지나서 다시 공부하면서 여기 정리해보았다.
튜토리얼과 설명을 제공하는 다양한 사이트들이 있고 직접 단계 별로 익혀보면 쉽게 익힐 수 있다.
이 글에 주로 정리하면서 참고한 것은 zvon.org의 내용이다. 아래는 참조했던 사이트들 목록이다.
https://zvon.org/comp/r/tut-Regexp.html
Regular Expressions Tutorial @ZVON.org
zvon.org
https://regexlearn.com/learn/regex101
Regex 101 - EN
You can learn the basics of Regex in this tutorial.
regexlearn.com
RegexOne - Learn Regular Expressions - Lesson 1: An Introduction, and the ABCs
Regular expressions are extremely useful in extracting information from text such as code, log files, spreadsheets, or even documents. And while there is a lot of theory behind formal languages, the following lessons and examples will explore the more prac
regexone.com
1. 정규 표현식 (Regular Expression)이란?
정규 표현식이란 특정한 규칙을 가진 문자열의 집합을 표현하는데 사용하는 형식언어이다. 프로그래밍 언어 같은 곳에서 문자열의 검색과 치환을 위한 용도로 간편하게 사용할 수 있다. 프로그램 코드를 작성할 때 일정한 규칙을 가진 텍스트 문자열을 사용하는 경우가 많은데 이럴 때 정규 표현식을 많이 사용한다.
위와 같이 글로 읽어보는 것보다 직접 하나씩 익혀보는 것이 이해가 가장 쉽다. 직접 정규식을 익히고 작성하면서 익히는 것이 가장 빠르다.
2. 정규 표현식 익히기
2-1. 문자열 검색하기
문자열 검색에 대해 알아보기 전에 먼저 정규 표현식에 대해 꼭 알아야할 내용들을 간단히 정리해보았다.
정규 표현식에는 정규 문자와 메타 문자가 있다.
정규 문자란 약속된 어떤 의미 없이 그대로 사용되는 문자를 말한다. 정규 문자 'a'는 'a'에 매칭된다.
반면 . ^ $ * + ? {} [] \ | () 과 같이 문자의 구성을 설명하기 위해 원래의 의미가 아닌 다른 의미로 쓰이는 문자를 메타 문자라고한다.
정규 표현식은 대소문자를 구분한다. (case-sensitive 라고 한다.) 또한 첫 번째 매칭 케이스(정규 표현식에 일치되는 문자열을 찾았을 경우)를 매칭하고 멈춘다.
그렇지만 플래그라는 것을 이용해 정규표현식의 동작 방식을 변경할 수 있다. 글로벌 플래그를 적용하면 문자열 전체에 대해 매칭 케이스를 찾아낸다. 또 case-insensitive(대소문자 구분 안함) 플래그를 적용하면 대소문자를 구분하지 않고 매칭 케이스를 찾아낸다.
참조한 zvon.org사이트에서는 첫 번째 매칭 케이스와 전체 매칭 케이스를 모두 보여준다. 대소문자는 항상 구분한다. 아래 정리해 둔 것도 그와 같은 방식으로 이루어져있다.
이제 정규 문자를 이용해 문자열을 검색하는 법에 대해 알아보자. 찾고자 하는 단어가 있다면 그대로 입력하면 된다. 일반적인 검색 과정과 비슷하다.
사례 1
소스 : Hello, world!
정규 표현식 : Hello
첫 번째 매치
Hello, world!
전체 매치
Hello, world!
사례1에서는 정규 표현식과 같은 단어인 Hello가 매칭된다.
사례 2
소스 : Hello, world!
정규 표현식 : hello
첫 번째 매치
Hello, world!
전체 매치
Hello, world!
정규 표현식은 대소문자를 구분하기 때문에 아무것도 매칭되지 않는다.
2-2. 공백 문자
정규 표현식에서 공백을 표현하는 문자들 스페이스(띄어쓰기, 스페이스바를 누르면 만들어진다), 탭, 줄바꿈 등은 모두 구분된다. 따라서 주의해야 한다.
사례 1
소스 : Hello, world!
정규 표현식 : Hello, world
첫 번째 매치
Hello, world!
전체 매치
Hello, world!
사례1에 'Hello,'와 'world' 사이에 있는 공백 역시 구분되기 때문에 주의해야한다.
사례 2
소스 : Hello, world!
정규 표현식 : Hello, world
첫 번째 매치
Hello, world!
전체 매치
Hello, world!
사례2에 'Hello,'와 'world' 사이에 있는 탭은 띄어쓰기와 구분되기 때문에 매칭되지 않는다.
2-3. 문자열의 위치와 이스케이프 문자
문자 ^와 $는 특별한 의미를 가지는 메타 문자이다. ^는 시작 부분에 매칭되고, $는 끝나는 부분에 매칭된다.
정규 표현식의 플래그에는 여러줄(multiline) 플래그 라는 것이 있는데 이 플래그를 켜지 않은 기본 상태에서는 소스가 여러줄일 경우에도 ^와 $는 전체 텍스트의 시작과 끝 부분에만 매치된다. 하지만 여러줄 플래그를 켜게되면 각 줄의 시작과 끝에 매치된다. 이 부분은 추후에 다시 정리할 예정이다.
사례 1
소스 : who is who
정규 표현식 : ^who
첫 번째 매치
who is who
전체 매치
who is who
^는 시작부분에 매칭되기 때문에 시작부분에 있는 who만 매칭된다.
사례 2
소스 : who is who
정규 표현식 : who$
첫 번째 매치
who is who
전체 매치
who is who
$는 끝나는 부분에 매칭되기 때문에 마지막 부분에 있는 who만 매칭된다.
위와 같은 특별한 의미를 가진 문자들을 특별한 의미가 아니라 문자 그대로 사용하고 싶을 수도 있다. 이럴때 \를 사용하면 된다. \를 이스케이프 문자라고 부르며 메타 문자 앞에 \를 붙여 이스케이핑 할 수 있다. \ 역시도 특별한 의미를 가진 문자이기 때문에 \를 문자 그대로 사용하고 싶다면 역시 이스케이프 해야한다.
사례 1
소스 : $12$ \-\ $25$
정규 표현식 : ^$
첫 번째 매치
$12$ \-\ $25$
전체 매치
$12$ \-\ $25$
^와 $ 모두 시작과 끝이라는 특수한 의미를 가지는 기호이다. 때문에 아무것도 매칭되지 않는다.
사례 2
소스 : $12$ \-\ $25$
정규 표현식 : \$
첫 번째 매치
$12$ \-\ $25$
전체 매치
$12$ \-\ $25$
$앞에 \를 사용해 이스케이프 시켰기 때문에 $는 문자 그 자체를 나타내게 된다. 그에 따라 $들이 매칭된다.
사례 3
소스 : $12$ \-\ $25$
정규 표현식 : ^\$
첫 번째 매치
$12$ \-\ $25$
전체 매치
$12$ \-\ $25$
^는 시작부분을 나타내고 \$는 문자 $를 그대로 나타내기 때문에 시작부분에 있는 $만 매칭된다.
사례 4
소스 : $12$ \-\ $25$
정규 표현식 : \$$
첫 번째 매치
$12$ \-\ $25$
전체 매치
$12$ \-\ $25$
\$는 문자 $를 그대로 나타내고 뒤에 있는 $는 끝 부분을 나타내기 때문에 마지막 부분에 있는 $만 매칭된다.
사례 5
소스 : $12$ \-\ $25$
정규 표현식 : \\
첫 번째 매치
$12$ \-\ $25$
전체 매치
$12$ \-\ $25$
\도 문자 그 자체를 나타내려면 \\와 같이 이스케이프 시켜 사용해야한다. \ 값들이 매칭된 것을 볼 수 있다.
2-4. 모든 문자
.은 모든 문자와 매칭된다. (줄바꿈은 제외이다.)
사례 1
소스 : Regular expressions are powerful!!!
정규 표현식 : .
첫 번째 매치
Regular expressions are powerful!!!
전체 매치
Regular expressions are powerful!!!
. 하나는 모든 문자와 매칭된다. 알파벳, 숫자, 공백 모두 상관없다.
사례 2
소스 : Regular expressions are powerful!!!
정규 표현식 : ......
첫 번째 매치
Regular expressions are powerful!!!
전체 매치
Regular expressions are powerful!!!
. 6개는 6개의 문자로된 문자열과 매칭된다. 어떤 문자든 상관 없다. 아래 전체 매치를 보면 ul!!!은 매칭 되지 않은 것을 볼 수 있다. 이를 6개의 문자로된 문자열로 나누어 보자.
Regula r expr ession s are powerf ul!!!
정규 표현식은 앞에서부터 매칭시켜 나간다. 따라서 6개의 문자로된 문자열을 매칭시키게되면 남는 ul!!!이 매칭되지 않는 것이다. 띄어쓰기 역시 하나의 문자임에 주의해야한다.
. 역시 의미를 가진 문자이기 때문에 문자 그대로 사용하려면 \를 이용해 이스케이프 시켜야한다.
사례 1
소스 : O.K.
정규 표현식 : .
첫 번째 매치
O.K.
전체 매치
O.K.
. 하나는 모든 문자와 매칭된다. 그에 따라 매칭된 것을 볼 수 있다.
사례 2
소스 : O.K.
정규 표현식 : \.
첫 번째 매치
O.K.
전체 매치
O.K.
이스케이프 문자를 앞에 썼기 때문에 정규 표현식이 . 문자 그 자체를 가리키게 된다. 따라서 첫 번째 .에 해당되는 부분이 매칭된 것을 볼 수 있다. 전체 매칭에서는 모든 .이 매칭된 것을 볼 수 있다.
사례 3
소스 : O.K.
정규 표현식 : \..\.
첫 번째 매치
O.K.
전체 매치
O.K.
정규 표현식을 앞에서부터 차근차근 보면 \. 은 문자 . 그 자체를, 그 다음 나오는 .은 모든 문자 하나를, 그 다음 나오는 \.은 문자 . 그 자체를 가리키는 것을 알 수 있다.
따라서 그에 맞는 .K.가 매칭된 것을 볼 수 있다.
2-5. 특정 문자
대괄호 [] 안에 문자 목록을 입력할 수 있고 이러한 문자들 중 하나라도 같다면 표현식이 매칭된다. 대괄호 안에 들어있는 문자의 순서는 상관이 없다. []안에 여러문자가 들어있으면 여러문자 같이 보이기 때문에 문자 여러개를 뜻한다고 착각할 수도 있겠지만 하나의 문자를 나타낸다.
사례 1
소스 : How do you do?
정규 표현식 : [oyu]
첫 번째 매치
How do you do?
전체 매치
How do you do?
[oyu] 문자가 o,y,u 중 하나이면 표현식이 매칭된다. 하나의 []는 하나의 문자와 매칭된다. 처음 o, y, u 문자 중 하나가 등장하게 되면 그것과 매칭되는 것을 볼 수 있다. 전체에서는 y,o,u 모든 문자가 매칭된 것을 볼 수 있다.
사례 2
소스 : How do you do?
정규 표현식 : [dH].
첫 번째 매치
How do you do?
전체 매치
How do you do?
[dH]는 d나 H 둘 중 하나의 문자를, .는 그 뒤에 나오는 모든 문자를 나타낸다. 따라서 H가 d보다 먼저 나왔기 때문에 H와 그 뒤에 이어지는 문자인 o가 같이 매칭되어 Ho가 매칭된 것을 볼 수 있다. 전체에서는 H,d와 그 뒤에 문자가 있으면 그 문자까지 같이 매칭된 것을 볼 수 있다.
사례 3
소스 : How do you do?
정규 표현식 : [owy] [yow]
첫 번째 매치
How do you do?
전체 매치
How do you do?
대괄호 안 문자의 순서는 상관이 없기 때문에 [owy]와 [yow]는 같다. y,o,w 중 하나의 문자가 연속으로 나오게 되는 문자열을 앞에서부터 찾게되면 제일 먼저 매치되는 것은 ow가 된다. 전체 매치에서는 yo가 추가로 매칭된 것을 볼 수 있다.
문자의 범위를 지정할 수도 있다. [-] 구문을 이용하면 되는데 아래 사례를 직접 보는 것이 더 이해가 빠를 것이다. 하나의 대괄호 안에 여러 범위를 지정할 수도 있다.
사례 1
소스
ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz 0123456789
정규 표현식 : [C-K]
첫 번째 매치
ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz 0123456789
전체 매치
ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz 0123456789
[C-K]는 C~K까지의 알파벳 전부를 뜻한다. [CDEFGHIJK]와 완전히 같다. 대괄호 []가 하나의 문자를 나타낸다는 점에 주의하자.
사례 2
소스
ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz 0123456789
정규 표현식 : [CDEFGHIJK]
첫 번째 매치
ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz 0123456789
전체 매치
ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz 0123456789
사례 1과 완전히 동일하다
사례 3
소스
ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz 0123456789
정규 표현식 : [a-d]
첫 번째 매치
ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz 0123456789
전체 매치
ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz 0123456789
[a-d]는 a~d까지의 알파벳을 나타낸다.
사례 4
소스
ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz 0123456789
정규 표현식 : [2-6]
첫 번째 매치
ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz 0123456789
전체 매치
ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz 0123456789
[2~6]은 2~6까지의 숫자를 나타낸다.
사례5
소스
ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz 0123456789
정규 표현식 : [C-Ka-d2-6]
첫 번째 매치
ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz 0123456789
전체 매치
ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz 0123456789
하나의 대괄호에 [C-Ka-d2-6] 같이 여러 범위를 넣어줄 수 있다. C~K까지의 알파벳, a~d까지의 알파벳, 2~6까지의 숫자를 나타낸다.
^는 줄의 시작을 가리키는 문자라고 배웠지만 대괄호 안에서 사용되면 not의 의미를 가지게 된다. 즉 대괄호 안에 들어있는 문자들이 아닌 문자가 선택된다.
사례 1
소스
ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz 0123456789
정규 표현식 : [^CDghi45]
첫 번째 매치
ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz 0123456789
전체 매치
ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz 0123456789
[ ^CDghi45]는 C,D,g,h,i,4,5가 아닌 모든 문자를 나타내게 된다. 그에 따라 매칭된 것을 볼 수 있다.
사례 1
소스
ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz 0123456789
정규 표현식 : [^W-Z]
첫 번째 매치
ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz 0123456789
전체 매치
ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz 0123456789
[^W-Z]는 W~Z의 알파벳이 아닌 모든 문자를 나타내게 된다.
'기타' 카테고리의 다른 글
동기 / 비동기, 블로킹 / 논블로킹 (0) | 2025.01.09 |
---|---|
정규 표현식 (3) (0) | 2024.12.19 |
정규 표현식 (2) (0) | 2024.12.18 |