TIL - 정규 표현식 I

한성봉·2021년 4월 27일
0

이 글은 도서 '점프 투 파이썬' 연습문제를 토대로 작성하였습니다.

정규 표현식

정규 표현식(Regular Expressions) 은 복잡한 문자열을 처리할 때 사용하는 기법으로 문자열을 처리하는 모든 곳에서 사용한다. 줄여서 정규식 이라고도 한다.

정규 표현식의 기초, 메타문자

정규 표현식에서 사용하는 메타문자(meta characters)에는 다음과 같은 것들이 있다.
메타문자 : 원래 그 문자가 가진 뜻이 아닌 특별한 용도로 사용하는 문자를 말한다.

. ^ $ * ? {} [] \ | ()
메타문자의 사용법을 알아보자

문자 클래스 []

문자 클래스[] 는 문자클래스로 만들어진 정규식은 [] 사이의 문자들과 매치라는 의미를 갖는다. 즉 정규표현식이 [abc] 라면 이 표현식의 의미는 a,b,c중 한 개의 문자와 매치를 뜻한다. 이해를 돕기 위해 문자열 "a","before","dude"가 정규식 [abc]와 어떻게 매치되는지 살펴보자.

정규식문자열매치여부설명
[abc]ayes"a"는 정규식과 일치하는 문자인 "a"가 있으므로 매치
[abc]beforeyes"before"는 정규식과 일치하는 문자인 "b"가 있으므로 매치
[abc]dudeno"dude"는 a,b,c 중 하나도 포함하고 있지 않으므로 매치되지 않음

[]안의 두 문자 사이에 하이픈(-)을 사용하면 두 문자 사이의 범위(from-to)를 의미한다.
ex) [a-c] = [abc] , [0-5] = [012345]

메타 문자 ^

메타 문자 ^는 문자 클래스안에 사용할 경우 반대(not)의 의미를 갖는다. 예를 들어 [^0-9]라는 정규식은 숫자가 아닌 문자만 매치된다.

자주 사용하는 문자 클래스

[0-9],[a-zA-Z]는 자주 사용하는 정규식이다. 자주 사용하는 정규식은 별도의 표기법으로 나타낼 수 있다.

정규 표현식설명
\d숫자와 매치,[0-9]와 동일한 표현이다.
\D숫자가 아닌 것과 매치, [^0-9]와 동일한 표현이다.
\swhitespace문자(공백을 표현하는 문자), [\t\n\r\f\v]와 동일한 표현식이다.
\S[^\t\n\r\f\v]과 동일한 표현식이다.
\w문자+숫자와 매치, [a-zA-Z0-9]와 동일한 표현식이다.
\W[^a-zA-Z0-9]와 동일한 표현식이다.

Dot(.)

정규표현식의 Dot(.) 메타 문자는 줄바꿈 문자인 \n을 제외한 모든 문자와 매치됨을 의미한다.

a.b 정규식을 살펴보자. 줄바꿈 문자를 제외한 어떠한 문자가 들어와도 모두 매치된다.

a + 모든 문자 + b 와 같은 의미이다. 아래 표를 통해 더 알아보자.

정규식문자열매치여부설명
a.baabyes"aab"는 가운데 문자 "a"가 모든 문자를 의미하는 .과 일치하므로 정규식과 매치
a.baObyes문자 "O" 가 모든 문자에 해당하므로 매치
a.babcno"abc"는 "a"문자와 "b"문자 사이에 문자가 없기 때문에 매치되지 않음

a[.]b 정규식

a[.]b = "a + Dot(.)문자 + b"
문자 클래스 []안에 . 이 들어가 있다면 이것은 Dot(.)의 의미가 아니라 문자 그대로의 .을 의미한다. 이것을 조심해서 보도록하자.

반복(*)

메타 문자 * : 바로 앞에 있는 문자가 0부터 무한대로 반복될 수 있다는 의미.
다음 예시를 살펴보자.

ex) ca*t # *문자 바로 앞에 있는 a가 0번 이상 반복되면 매치

정규식문자열매치여부설명
ca*tctyes"a"가 0번 반복되어 매치
ca*tcatyes"a"가 0번 이상 반복되어 매치(1번 반복)
ca*tcaaatyes"a"가 0번 이상 반복되어 매치(3번 반복)

반복(+)

메타 문자 + : +는 최소 1번 이상 반복될 때 사용한다.
다음 예시를 살펴보자

ex) ca+t #문자 바로 앞에 있는 a가 1번 이상 반복되면 매치

정규식문자열매치여부설명
ca+tctno"a"가 0번 반복되어 매치되지 않음
ca+tcatyes"a"가 1번 이상 반복되어 매치(1번 반복)
ca+tcaaatyes"a"가 1번 이상 반복되어 매치(3번 반복)

반복({m, n}, ?)

메타 문자 {} : 반복횟수를 고정할 때 사용 반복 횟수를 m~n까지 고정할 수 있다.

  • {3,} : 3회 이상 반복
  • {,3} : 3회 이하 반복
  • {1,} = +
  • {0,} = *

1. {m}

ca{2}t # a가 2번 반복되면 매치
ca{2}t = c + a(반드시 2번 반복)+ b

정규식문자열매치여부설명
ca{2}tcatno"a"가 1번 반복되어 매치되지 않음
ca{2}tcaatyes"a"가 2번 반복되어 매치

2. {m, n}

ca{2,5}t # a가 2~5번 반복되면 매치
ca{2,5}t = c +a(2~5번 반복) + t

정규식문자열매치여부설명
ca{2,5}tcatno"a"가 1번 반복되어 매치되지 않음
ca{2,5}tcaatyes"a"가 2번 반복되어 매치
ca{2,5}tcaaaaatyes"a"가 5번 반복되어 매치

3. ?

메타 문자 ? = {0, 1}
ab?c = a + b(있어도 되고 없어도 된다) +c # b가 0~1번 사용되면 매치

정규식문자열매치여부설명
ab?cabcyes"b"가 1번 사용되어 매치
ab?cacyes"b"가 0번 사용되어 매치
  • ^,,? 메타 문자는 모두 {m, n} 형태로 표현할 수 있지만 가급적 이해하기 쉽고 표현도 간단한 메타문자로 사용하는 것이 좋다

파이썬에서 정규 표현식을 지원하는 re모듈

파이썬은 정규 표현식을 지원하기 위해 re(regular expression) 모듈을 제공한다. re모듈은 파이썬을 설치할 때 자동으로 설치되는 기본 라이브러리로 사용방법은 다음과 같다.

import re
p = re.compile('ab*')

re.compile을 사용해 정규식을 컴파일한다.re.compile 의 결과로 돌려주는 객체 p(컴파일된 패턴 객체)를 사용하여 그 이후의 작업을 수행할 것이다.

  • 패턴 : 정규식을 컴파일한 결과

정규식을 사용한 문자열 검색

메서드목적
match()문자열의 처음부터 정규식과 매치되는지 조사
search()문자열 전체를 검색하여 정규식과 매치되는지 조사
findall()정규식과 매치되는 모든 문자열을 리스트로 반환
finditer()정규식과 매치되는 모든 문자열을 반복 가능한 객체로 반환

검색 메서드를 사용하기 위해서는 다음과 같은 코드를 작성한다.

import re
p = re.compile(정규식)

m = p.match/search/findall/finditer(조사할 문자열)
print(m) # m이라는 객체에 대입

match 객체의 메서드

메서드목적
group()매치된 문자열을 돌려준다
start()매치된 문자열의 시작 위치를 돌려준다
end()매치된 문자열의 끝 위치를 돌려준다
span()매치된 문자열의(시작, 끝)에 해당하는 튜플을 돌려준다.

match 객체의 메서드 사용 방법을 살펴보자.

import re

p = re.compile('[a-z]+')
m = p.match("python")

print(m.group()) # 'python'
print(m.start()) # 0
print(m.end()) # 6
print(m.span()) # (0, 6)

만약 search를 사용했을 때 차이점을 살펴보자.

import re

p = re.compile('[a-z]+')
m = p.search("3 python")

print(m.group()) # 'python'
print(m.start()) # 2
print(m.end()) # 8
print(m.span()) # (2, 8)

컴파일 옵션

옵션 이름약어설명
DOTALLSdot문자(.)가 줄바꿈 문자를 포함하여 모든 문자와 매치
IGNORECASEI대,소문자와 관계 없이 매치
MULTILINEM여러 줄과 매치(^,$ 메타 문자 사용과 관계 있음)
VERBOSEXverbose 모드를 사용(정규식을 보기 편하게 하고 주석 사용 가능)

백슬래시 문제

만약 \section이라는 문자열을 찾는다고 가정해보자. 이 문자열은 \s가 whitespace 로 해석되어 의도한 대로 매치가 이루어지지 않는다.

\section = [\t\n\r\f\v]ection 둘은 동일한 의미이다.

의도한 대로 문자열을 조사하고 싶으면 \\section으로 변경해야한다.

하지만 파이썬에서 이렇게 사용할 경우 파이썬 문자열 리터럴 규칙에 따라 \\\으로 자동으로 변경된다. 이처럼 파이썬에서 \\문자를 전달하려면 \\\\ 백슬래시 4개를 사용해야한다.
하지만 백슬래시를 4개나 사용하는 것은 코드 줄이 길어질 경우 가독성과 효율이 떨어질 수 있다.

이를 해결하기 위해 파이썬에서는 Raw String 규칙이 생겨나게 되었다.
즉 컴파일해야하는 정규식이 Raw String임을 알려 줄 수 있도록 파이썬 문법을 만든 것이다.

p = re.compile(r'\\section')
정규식 문자열 앞에 r문자를 삽입하면 정규식은 Raw String 규칙에 의하여 백슬래시 2개 대신 1개만 써도 2개를 쓴 것과 동일한 의미를 갖는다.

0개의 댓글