[코드잇] 정규 표현식
◆ 기본 문법
◆ 심화 문법
정규 표현식
정규 표현식 Regular Expression, Regex
- 실제 값은 다르지만 패턴은 서로 동일한 문자열을 표현할 때 사용되는 형식 언어
- 프로그래밍 언어에 따라 지원되는 정규 표현식 문법에 조금씩 차이가 있음.
- 일반적인 정규 표현식에서는 대문자와 소문자를 구분함.
- 시작기호 + 정규식 패턴 + 종료기호 + 플래그
ex. /[bce]ar/gi
regex101: build, test, and debug regex
Regular expression tester with syntax highlighting, explanation, cheat sheet for PHP/PCRE, Python, GO, JavaScript, Java, C#/.NET, Rust.
regex101.com
- FLAVOR : 지원할 언어 설정
- TEST STRING : 실습할 텍스트 본문 입력
- REGULAR EXPRESSION : 원하는 정규 표현식 작성, TEST STRING 부분 중 일치하는 부분이 하이라이트 됨.
- EXPLANATION : 화면으로 보여줌. 문법에 대한 설명도 있음.
- MATCH INFORMATION : 필요한 정규 표현식 문법을 검색하고 찾을 수 있음.
regex101 사이트의 정규표현식 작성 부분은 기본적으로 gm 플래그가 설정되어 있음.
기본 문법
집합
- 표현하고 싶은 문자를 대괄호([]_에 넣는 식
- 대괄호 안에 들어간 문자들은 or 연산이 적용되어 집합 안에 있는 문자 중 하나라도 매칭되면 선택됨.
[bce]ar
bar, car, ear 모두 선택
[0123456789]
하이픈 제외하고 숫자만 출력됨.
[ABCDEFGHIJKLMNOPQRSTUVWXYZ][abcdefghijklmnopqrstuvwxyz]/gm
대문자+소문자가 붙어서 나오는 부분만 선택됨.
[0-9A-Z]/gm
숫자 혹은 영어 대문자만 찾아줌.
하이픈(-)
문자 사이의 범위를 나타냄.
- 숫자: [0-9]
- 영어 소문자 : [a-z]
- 영어 대문자 : [A-Z]
- 한글(자음 모음 조합) : [가-힣]
캐럿(^)
집합 안의 특정 문자들을 제외하여 선택하고 싶을 때 사용함.
부정의 의미로 사용할 때는 집합의 가장 처음에 위치해야 함.
[^a-z]
알파벳 소문자 a부터 z를 제외한 나머지만 출력됨.
a만 제외되는 것이 아니라, a부터 z가 제외되는 것임.
[0-9^a-z]
- 숫자는 포함, 알파벳 소문자는 제외 (X)
- 숫자, '^'라는 문자, 소문자 선택 (O)
하이픈 사용 시 주의점
- 정규표현식은 특정 문자를 어떤 숫자로 인코딩할지를 아스키코드의 규칙에 따라서 정함.
- 하이픈을 사용해서 범위를 지정할 때에는 왼쪽에는 아스키코드가 낮은 문자, 오른쪽에는 아스키코드가 높은 문자를 위치하도록 해야함.
하이픈 문법을 [A-z]나 [A-9]처럼 사용하면 예상하지 못한 결과가 나옴.
[A-z]
· 아스키코드 65번부터 122번 안의 모든 문자를 선택하겠다는 의미임.
· 65번과 122번 사이의 특수문자까지 포함되어 의도치 않은 결과가 나옴.
[A-z]/gm
[A-9]
· 아스키코드 65~57번을 나타내므로 문법에 어긋나서 아무것도 선택되지 않음.
[A-9]/gm
ASCII table - Table of ASCII codes, characters and symbols
A complete list of all ASCII codes, characters, symbols and signs included in the 7-bit ASCII table and the extended ASCII table according to the Windows-1252 character set, which is a superset of ISO 8859-1 in terms of printable characters.
www.ascii-code.com
문자 클래스
자주 사용하는 집합들을 쉽게 사용할 수 있도록 한 예약어
보통 백슬래시(\) 뒤에 특정 알파벳을 합쳐서 표기함.
의미 | 집합 표현 | 문자 클래스 |
숫자 | [0-9] | \d |
숫자가 아닌 것 | [^0-9] | \D |
영어 대소문자 + 숫자 + _(언더바) | [a-zA-Z0-9_] | \w |
영어 대소문자 + 숫자 + _(언더바) + 한글 | [a-zA-Z0-9_가-힣] | \w가-힣 |
공백 문자 (스페이스바, 탭 등) | [ \t\n\r\f\v] | \s |
공백 문자가 아닌 것 | [^ \t\n\r\f\v] | \S |
메타 문자
정규 표현식에서 원하는 방식으로 규칙을 찾게 해주는 예약어
대괄호([ ]), 하이픈(-), 캐럿(^), 문자 클래스 등도 모두 다 메타 문자에 속함.
Dot(.)
· 모든 문자를 의미함.
· 숫자, 알파벳, 특수 문자, 공백, 한글 등을 포함함.
· 줄바꿈문자(\n)은 포함되지 않음.
→ s 플래그(single line)를 설정하면 줄바꿈 설정이 가능해짐.
/l../gm
/go.home/gm
/go.home/gms
이스케이핑
기존 예약어를 일반문자로 사용하고 싶을 때 이스케이핑 문자를 사용함.
/./gm
마침표를 선택하고 싶은데 '.'이 예약어라서 의도와 다르게 작용함.
/\./gm
이스케이핑(\) 처리를 통해 마침표(.)만 출력됨.
슬래시(/)도 이스케이핑 처리를 해야함.
/10/5=2/gm ---> X
/10\/5=2/gm ---> O
백슬래시(\)는 두 번 써야 이스케이핑 처리가 됨.
/c:\user\download/gm ---> X
/c:\\user\\download/gm ---> O
수량자
여러 번 반복되는 문자나 문자열을 선택할 때 문자의 반복 횟수를 설정하는 문법
중괄호{} 안에 원하는 반복횟수를 넣어주는 방식으로 표현함.
네 자리 숫자 표현
[0123456789][0123456789][0123456789][0123456789]
[0-9][0-9][0-9][0-9]
\d\d\d\d
\d{4}
수량자 범위 지정: {min,max}
· 최솟값과 최댓값 사이는 콤마 앞뒤에 공백 없이 입력해야 함.
· 최솟값은 빈칸으로 두는 것이 불가능, 최댓값은 빈칸으로 두는 것이 가능함.
3자리 ~ 6자리인 수
\d{3,6}
세자리 이상인 수
\d{3,}
1부터 최댓값 자리인 수
\d{,6} ---> 불가능
\d{1,6} ---> 가능
수량자의 메타문자
- * : 제한 없이 모든 숫자를 나타냄. 앞에 문자가 하나도 없어도 선택해줌.
- + : 제한 없이 모든 숫자를 나타냄. 앞에 최소 1개의 문자(숫자)가 필요함.
- ? : 문자가 아예 없거나 하나만 있을 경우(0번 혹은 1번 반복) 선택해줌.
\d*원 ---> '원' 가능
\d+원 ---> '원' 불가능
수량자의 종류
- 탐욕적 수량자 : 정규표현식에 부합하는 여러 케이스가 있을 때 가장 큰 덩어리의 문자열을 선택해 주는 수량자
- 게으른 수량자 : 문자를 원하는 만큼 일치시키기 위해 사용하는 수량자
수량자 사용 시 주의할 점
*, +, {min,} 등 반복되는 최대 개수의 제한이 없는 수량자를 사용할 때에는 정확하게 원하는 부분만 선택되지 않을 수 있음.
큰따옴표에 둘러싸인 문자열을 찾으려면
/".*"/gm
각각 선택된 것이 아니라 공백까지 포함하여 산번에 선택됨.
따옴표 사이에 공백이 있어서 이런 결과가 출력됨.
수량자 *가 최대한 큰 덩어리의 문자열을 찾으려고 하는 특성(greedy) 때문임.
?
· 단독으로 쓰이면 0또는 1번 반복되는 문자를 찾는 수량자
/jpe?g/gm
jpg 또는 jpeg를 나타냄
· 다른 수량자와 중첩해서 사용될 때에는 앞에 온 수량자가 게으른 수량자게 되도록 함
/".*?"/gm
정확하게 "Apple" "Banana" "Cake"가 각각 선택됨.
경계
단어 경계
- \b : 문자(\w)와 문자가 아닌 곳(\W) 사이의 위치에 해당하는 경계
- \B : 단어의 경계가 아닌 위치
ex. 'This island is beautiful'에서 정확히 'is'만 출력하고 싶은 경우
문장 경계
- 문장의 시작점을 의미하는 캐럿(^)과 문장의 끝지점을 의미하는 달러 기호($)
- 캐럿은 집합 안에서 쓰이면 부정, 집합 바깥에서 쓰이면 경계의 의미
하위 표현식
- 전체 정규 표현식 안에서 특정 패턴을 나타내는 표현식을 하나의 항목으로 처리하는 것
- 메타 문자 소괄호()를 사용해 나타냄.
- 용도 : 가독성, 표현식의 반복, OR(|) 연산 활용
가독성
# Without Subexpression
\d{3}-\d{2}-\d{4}
# With Subexpression for Social Security Number
(\d{3}-\d{2}-\d{4})
표현식의 반복
# Without Subexpression
(https?|ftp)://(www\.)?example\.com
# With Subexpression for Domain
(https?|ftp)://(www\.)?(example\.com)
OR 연산자 활용
# Without Subexpression
apple|orange|banana
# With Subexpression for Fruits
(apple|orange|banana)
플래그 옵션 정리
플래그 : 정규 표현식에 적용되는 설정을 조절해주는 옵션
- g : 패턴과 일치하는 모든 것을 찾음. (생략시 가장 먼저 발견한 것만 하나 찾음)
- i : 대소문자 구분없이 알파벳이 일치하면 선택해줌.
- m : 문자열을 여러 줄로 인식함(multiline). 줄바꿈이 된 곳을 문장의 경계로 인식할 수 있음.
- s : 메타문자 Dot(.)이 줄바꿈 문자도 포함하도록 설정함.
심화 문법
역참조
- 한번 만든 하위 표현식은 역참조를 통해 재사용할 수 있음.
- 재사용 : 하위 표현식에 일치하는 문자열을 추출하여 다른 곳에서 그 패턴을 사용할 수 있음.
- JavaScript 환경에서는 역참조에 백슬래시(\)를 활용함.
한 번 사용된 단어가 반복해서 나온 경우 찾기
(\w+)\s\1
- \1 : 앞에서 하위 표현식으로 만들었던 (\w+)를 다시 재사용하기 위하여 호출한 부분
치환
특정 패턴과 일치하는 문자열을 찾아서 원하는 문자열로 바꿔주는 것.
치환에선 공백 문자(\n, \t 등)와 역참조($)를 제외하고는 문법으로 사용되는 문자가 따로 없음.
- 검색 : \ + 그룹번호
- 치환 : $ + 그룹번호
.txt를 .docx로 바꿔주기
전방탐색과 후방탐색
하위 표현식이지만 결과에는 반영되지 않고 특정 문자열을 찾기 위한 조건 역할만 하는 문법
전방탐색(lookahead)
- 문자열의 앞부터 문자열을 탐색하여 조건에 해당하는 부분이 확인되면 해당 조건 뒤쪽 부분을 생략하기 위해 사용됨.
- (?= ) 형태로 사용
후방탐색(lookbehind)
- 문자열을 뒤쪽부터 탐색하여 조건에 해당하는 부분이 있는지 확인하고, 해당 조건에 해당하는 문자열에 대하여 후방탐색이 걸린 부분을 제외한 나머지 값들을 선택
- (?<= ) 형태로 사용
부정 전방탐색 : 일치하지 않는 조건을 거는 데 사용, (?! )
부정 후방탐색 : 일치하지 않는 조건을 거는 데 사용, (?<! )