정규표현식 Regular Expression
목차
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
정규 표현식(Regular Expression)이란?
- 문자열에서 특정한 패턴을 찾기 위한 표현식이다.
- 예) 전화번호, 이메일 주소, 학번 등
- python에서는 정규 표현식을 통해 문자열 내에서 특정 표현식을 '검색', '치환', '제거' 할 수 있는 함수를 제공한다.
정규표현식을 어떻게 작성하는가?
코드에서 문자열 앞에 r을 붙이면, 정규표현식으로 인식한다.
+ 정규식에서 백슬래쉬(\)는 다른 문자와 같이 쓰이며, 특수한 의미를 갖는다.
python에서도 백슬래쉬를 탭이나 줄바꿈을 나타내는 의미로 쓰이기 때문에 충돌을 낳음. (e.g. \t, \n)
해결책 - 문자열 앞에 r을 붙이면, 백슬래쉬를 정규표현식으로 인식한다.
Python re 모듈 함수들
대표적으로 match(), search(), findall(), sub() 함수가 있다.
(1) match(patttern, string): 문자열의 시작 부분에서 정규식이 일치하는지 체크
- result : 일치하는 게 있으면 Match 오브젝트를, 일치하지 않으면 None을 반환
print(re.match(r'From\s', 'From now on')) # <re.Match object; span=(0, 5), match='From '>
print(re.match(r'From\s', 'now on, From local.. ')) # None
(2) search(patttern, string): 문자열 전체에서 정규식이 일치하는 첫 번째 부분을 찾는다.
- result : 일치하는 게 있으면 Match 오브젝트를, 일치하지 않으면 None을 반환
- 아래 코드를 보면 시작 뿐만 아니라, 중간에 있는 From\s 도 찾을 수 있음. cf) match()
print(re.search(r'From\s', 'From now on')) # <re.Match object; span=(0, 5), match='From '>
print(re.search(r'From\s', 'now on, From local.. ')) # <re.Match object; span=(8, 13), match='From '>
(3) findall(patttern, string): 문자열 내에서 정규식 패턴과 일치하는 모든 부분을 찾아서 리스트로 반환한다.
- result : 일치하는 게 있으면 lst를 , 일치하지 않으면 빈 리스트 반환
pattern1 = r'\d+' # 숫자에 매칭되는 패턴
pattern2 = r'\^' # '^'에 매칭되는 패턴
string = "abc123xyz456def"
print(re.findall(pattern1, string)) # ['123', '456']
print(re.findall(pattern2, string)) # []
(4) sub(patttern, replacement, string): 문자열 내 정규식 패턴과 일치하는 모든 부분을 다른 문자열로 바꿔줌
import re
pattern = r'\d+' # 숫자에 매칭되는 패턴
replacement = '#'
string = "abc123xyz456def"
sub = re.sub(pattern, replacement, string)
print("Sub result:", sub)
정규표현식 문법
자료형
이때 백슬래쉬(\)는 다른 문자와 같이 쓰이며, 특수한 의미를 갖는다.
- \d: 숫자 1개 = [0-9]
- \D: 숫자가 아닌 것 1개 = [^0-9]
- \w 글자 1개- ‘0’, ‘a’ 포함 + 특수문자는 ‘_’만 포함 = [a-zA-Z0-9_]
- \W: 글자 제외한 것 1개(공백, 특수문자 등) = [^a-zA-Z0-9_]
- \s: 공백 문자 1개(스페이스, 탭, 뉴라인 등) = [\t\n\r\f\v]
- \S: 공백 제외 문자 1개= [^\t\n\r\f\v]
- . : \n(개행문자)를 제외한 모든 문자 중 1개
- a.b - "a0b", "aab" "a b" (O) / "abc", "a\nb"(X)
- cf) [.]은 정확히 '.' 과 매치되며, 개행 문자를 제외한 문자 1개를 나타내는 것 X
- .x: x로 끝나는 모든 단어
Boundaries
- \b: 단어의 경계를 나타냄
- 문자열의 시작도 단어의 경계임을 유의(1번째 예시)
print(re.search(r'\bhello\b', 'hello world ', )) #match
print(re.search(r'\bhello\b', ' hello world ', )) #match
print(re.search(r'\bhello\b', 'helloworld ', )) #do not match
- \B: 단어의 경계에 있지 않을 때
print(re.search(r'\Bhello\B', 'hello world ', )) # None
print(re.search(r'\Bhello\B', ' hello world ', )) # None
print(re.search(r'\Bhello\B', ' songnamehelloworld ', )) # match
- ^ 줄의 시작
- e.g. ^From 은 'From'으로 시작하는 문자열을 찾아줌
- $ : 줄의 끝 부분(문자열의 끝이나 줄바꿈 문자)인지 나타냄
- 그냥 띄어쓰기나 탭으로 끝나는 문자는 매치가 안된다.
Quantifiers
문자를 얼마나 반복할 것인지를 나타내는 역할을 한다.
모두 기호 앞에 있는 문자의 양을 관장한다.
- *: 0개 or 1개 이상
- \d*: 숫자가 없거나 1개 이상 e.g. '', '12', '12345'
- ab*: 'a', 'ab', 'abb...' (O), 'ac' (X)
- + : 하나 혹은 그 이상의 문자열
- \d+: 하나 혹은 그 이상의 숫자 문자열 집합 e.g. '12', '12345'
- ab+: 'abc', 'abc...' cf) ab*는 'ab'이 포함되지만, ab+은 아니다.
- ?: 있거나 없거나(1 or 0)
- a? 1개가 있거나 없거나. e.g. ab? : 'a' or 'ab'와 일치
- [ab]? 둘 중 1개가 있거나 없거나 e.g. [ac]? 'a', 'c', 'ac'와 일치 <-> 'bd' (X)
- {} : 반복을 관장함
- {N}: 특정 문자(열)을 N번 반복함 e.g. \d{2}: 숫자가 2개 e.g. 11, 22
- {N, }: 특정 문자(열)을 최소 N번 반복함 e.g. \d{2,}: 숫자가 2개 e.g. 11, 22
- {N,M}: 인자가 2개 일 때는 특정 문자(열)을 N번이상 M번 이하 반복한다.
- e.g. \d{2,3}: 숫자가 2~3 e.g. "010", "01"
GROUP
문자 집합을 나타내는데 사용된다.
- []: [] 안의 어떤 문자이든 1개
- 문자 1개 지정 e.g. [aeiou]: 'a', 'e', 'i', 'o', 'u' 와 매치
- 범위 사용 [N-M]
- 숫자 범위 [1-9], [0-9]
- 한국어 찾기 : [가-힣]
- 영문 소문자 : [a-z], 대문자 [A-Z]
- [^]: ^의 뒤에 오는 문자를 제외한 모든 문자와 일치
- 예) [^5]: 5 제외한 문자와 일치 cf) [5^] : '5' or ^와 일치
- | : OR
- () : 그룹
- (ab)*은 ab가 0번 이상 반복되는 모든 문자열에 대한 정규식이다.
특정 문자열 탐색
- 긍정형 전방탐색: 탐색키워드 앞에 정규식을 만족하는 문자열을 찾음
- 형식: '정규식표현(?={탐색키워드})'
- e.g. "/d(?= dollars)" "dollars" 앞에 있는 숫자를 찾음
- 010-1234-5678 : '\d{4}(?=-)' '-'앞에 있는 4개 숫자를 찾음
- 형식: '정규식표현(?={탐색키워드})'
- 부정형 전방탐색: 탐색키워드 뒤에 정규식을 만족하는 문자열을 찾음
- 형식: '(?={탐색키워드})정규식표현'
- e.g. "(?= dollars)/d" "dollars" 앞에 있는 숫자를 찾음
- cf) "(?! dollars)/d": dollars 앞에 있는 숫자 찾음
- e.g. "(?= dollars)/d" "dollars" 앞에 있는 숫자를 찾음
- 형식: '(?={탐색키워드})정규식표현'
헷갈리는 Point
- 반복문 * vs +
- * 은 0개 이상 vs + 는 1개 이상
- 나는 0을 더하면(+)는 값의 변화가 없지만, 곱하면(*) 값이 달라지기 때문에 *은 0이상이라고 외웠다.
- ^
- [] 안에 있을 때 - [^] : 앞에 있는 문자의 여집합
- 그냥 나타날 때: 줄의 시작 e.g. ^From 은 'From'으로 시작하는 문자열을 찾아줌
- 정말 리터럴한 '^' 을 찾고 싶으면 '\^'을 사용해라
- $ : 줄의 끝 부분(문자열의 끝이나 줄바꿈 문자)인지 나타냄
- 그냥 띄어쓰기나 탭으로 끝나는 문자는 매치가 안된다.
- 리터럴한 $을 찾고 싶으면 '\$' 사용!
- [] 안에 특수문자가 들어가면 특수한 의미를 상실한다.
- 예) [(+*)]은 리터럴 문자 '(', '+', '*' 또는 ')'와 일치합니다.
- \가 붙으면 special 한 의미가 사라진다.
- 예를 들어 '\.' 은 리터럴 '.' 과 일치되는 것을 보여줌.
Reference
[Python] 정규표현식과 re모듈 사용법
학습목표 정규표현식(re)에 대한 이해 및 숙지 정규표현식이란? regular expression 특정 패턴에 상응하는 문자열을 '검색', '치환', '제거' 하는 기능을 가짐 정규표현식의 도움없이도 패턴을 찾는 작
cdragon.tistory.com
Regular Expression HOWTO
Author, A.M. Kuchling < amk@amk.ca>,. Abstract: This document is an introductory tutorial to using regular expressions in Python with the re module. It provides a gentler introduction than the corr...
docs.python.org
정규표현식을 공부해보자
정규표현식(regEx)의 기본 형태, 패턴, 플래그를 알아보고 실 적용 예시를 간단한 프로그래머스 문제로 알아보자
velog.io
기초 실습하며 공부할 수 있는 사이트
https://school.programmers.co.kr/learn/courses/11/lessons/132