정규표현식은 특정한 규칙을 지닌 문자열의 집합에 대한 표현식이다. 정규표현식이 사용될 예시는 아래와 같다.
- E-mail 주소(abcd@efg.com) 형태의 문자열인지 확인하고 mailto: 처리를 하려 할 때
- 어떤 프로그램의 로그 파일 중 특정 이벤트나 메시지만을 필터링 하려는 경우
- IDE의 도움 없이 코드에서 특정 변수만 이름을 변경하고자 하는 경우
위와 같이 주어진 문자열 속에서(대부분 긴) 내가 원하는 문자열을 패턴화 시켜 추출해내고, 교체할 수 있게 해 준다. 거의 대부분의 프로그래밍 언어는 정규표현식 기능을 제공한다.
기초 정규표현식
본 포스트에서는 문자열 추출을 위해 필요한 가장 기초적인 기호 및 사용법에 대하여 설명한다. 좀 더 효율적으로 표현하기 위해 중요한 기술이나, 치환 등에 필요한 내용은 다음 포스트에서 다루도록 하겠다. 아래에서 설명하는 정규표현식의 표현법은 프로그래밍 언어, 환경마다 다를 수 있다. $var 는 변수를 표현하기 위함이다. 해당 문자열에 $가 포함된다는 뜻이 아니다.
1. 리터럴 문자
기초적인 문자(일부 특수 기호)를 표현한다.
기호 | 의미 | 예시 / 추가 설명 |
---|---|---|
$text | $text 문자열 그대로 추출 | /LINE/ -> INLINE 일치 |
\t | \v | 수평 | 수직 방향 탭 을 표현함 | 예시 / 추가 설명 불필요 |
\r | 캐리지 리턴을 표현함 | 예시 / 추가 설명 불필요 |
\n | 줄넘김 (개행 문자) 을 표현함 | 예시 / 추가 설명 불필요 |
\f | 페이지 넘김을 표현함 | 예시 / 추가 설명 불필요 |
\\ | 역슬래시 문자를 표현 | 예시 / 추가 설명 불필요 |
\x$HX | 16진수 $HX 의 값을 추출 | /\x61/ -> abcab 일치 (0x61 == ‘a’) |
\0$OCT | 8진수 $OCT 의 값을 추출 | 예시 / 추가 설명 불필요 |
위의 표에 나와있는 항목 외에도 정규표현식에서 사용하는 특수문자들을 리터럴 값으로 표현하기 위해 \로 escape를 사용한다. 하지만 정규표현식을 사용하는 환경에 따라 escape를 한 것을 리터럴로 취급하는지 혹은 반대인지 차이가 있을 수 있다.
2. 문자 클래스
1개의 문자를 추출하기 위해, 비슷한 부류의 문자들을 종류에 따라 묶어 표현한다.
기호 | 의미 | 예시 / 추가 설명 |
---|---|---|
[$keys] | $keys에 속하는 모든 문자 | /[01234]/ -> ‘0’, ‘1’, ‘2’, ‘3’, ‘4’ 일치 |
[$a-$b] | $a에서 $b 범위에 속하는 모든 문자 | /[0-4]/ == /[01234]/ |
[^$a] | $a를 제외한 모든 문자 | /[^0-9]/ -> 숫자를 제외한 모든 글자 일치 |
. | 개행 문자를 제외한 모든 문자 | 예시 / 추가 설명 불필요 |
\w | 알파벳(대+소), 숫자, _에 해당하는 모든 문자 | /\w/ == /[A-Za-z0-9_]/ |
\W | 알파벳(대+소), 숫자, _를 제외한 모든 문자 | /\W/ == /[^A-Za-z0-9_]/ |
\d | 모든 숫자(0~9) 문자 | /\d/ == /[0-9]/ |
\D | 모든 숫자를 제외한 모든 문자 | /\D/ == /[^0-9]/ |
\s | 모든 빈칸(스페이스, 탭, 줄바꿈) 문자 | /\s/ == /[ \t\r\n\v\f]/ |
\S | 모든 빈칸(스페이스, 탭, 줄바꿈)을 제외한 문자 | /\S/ == /[^ \t\r\n\v\f]/ |
3. 수량자
수량자를 통해 패턴의 표현 횟수를 줄이거나, 유연하게 처리하게 할 수 있다.
기호 | 의미 | 예시 / 추가 설명 |
---|---|---|
{$t} | 앞의 표현식을 $t번 반복하는 부분을 추출 | /[\da-fA-F]{2}/ -> 2자리 16진수 일치 |
{$t,} | 앞의 표현식을 $t번 이상 반복하는 부분을 추출 | /\d{5}/ -> 5자리 이상의 숫자 일치 |
{$s,$e} | 앞의 표현식을 $s번 이상, $e번 이하 반복하는 부분을 추출 | /\d{3,5}/ -> 3~5자리의 숫자 일치 |
? | 앞의 표현식이 0번 혹은 1번 나타나는 부분을 추출 | /https?/ -> http, https 일치 |
* | 앞의 표현식이 0번 이상 나타나는 부분을 추출 | /\w*/ == \w{0,} |
+ | 앞의 표현식이 1번 이상 나타나는 부분을 추출 | /\d+/ == \d{1,} |
수량자에는 추가적으로 게으른 문자(lazy evaluation)라는 개념이 있는데 이는 나중에 따로 다루도록 하겠다.
4. 그룹 조건
수량자를 표현식 단위로 적용하거나, 표현식 여러 개를 묶어 OR 연산을 할 수도 있다.
기호 | 의미 | 예시 / 추가 설명 |
---|---|---|
($exp) | 표현식 $exp를 묶어 수량자 연산 등을 가능케 함 | /(0x[\da-fA-F]{2} ?)+/ -> 16진법 배열 일치 |
($e1|$e2) | 표현식 $e1 이나 $e2 중 해당하는 부분을 추출 (OR) | /(Str|string)/ -> Str, string 일치 |
5. 위치 지정
문자열 추출시 위치에 대한 조건을 둘 수 있다. 여기에서 $는 변수를 뜻하는 것이 아니라 글자 ‘$‘를 뜻하는 것이다. 여기에서 설명하는 문자열은 일반적으로 \r 혹은 \n으로 구분되는 문장을 뜻한다. 단어의 기준은 일반적으로 \s (스페이스, 탭, 줄바꿈) 사이의 글자들을 말한다.
기호 | 의미 | 예시 / 추가 설명 |
---|---|---|
^ | 문자열의 시작 부분 | /^An/ -> 문자열의 시작의 An Ancestor 에서 맨 앞의 An만 일치 |
$ | 문자열의 끝 부분 | /er$/ -> 문자열의 끝의 better stronger 에서 맨 끝의 er만 일치 |
\b | 단어의 경계 | /\bor/ -> organ, inventor 는 일치하지만 bored는 일치하지 않음 |
\B | 단어의 중간 | /\Bor/ -> bored 는 일치하지만 organ, inventor는 일치하지 않음 |
정규표현식 관련 사이트
- 언어/환경별 정규표현식 표현 비교 표
- 정규표현식 공부할 수 있는 사이트
- regexone : 설명을 보고 아래 예제를 맞추는 방식으로 진행하는 형태
- regexcrossword : 가로세로 퍼즐처럼 문제풀이 (확인용)
- 언어/환경별 정규표현식 실험 사이트
- https://regexr.com/ (Javascript, PCRE)
- http://regexstorm.net/tester (.NET)
- http://www.regexplanet.com/advanced/java/index.html (Java)
- 정규표현식 자동 생성
- txt2re : 문자열을 입력하면 각 부분마다 표현하기 위한 정규표현식을 자동 생성해줌