[Python] 정규 표현식(1) - 문자 클래스, Dot(.), 반복(*), 반복(+), 반복({m,n}, ?)

미남로그·2021년 9월 14일
1
post-custom-banner

저는 점프투파이썬 교재로 공부합니다. 이 교재를 바탕으로 공부한 걸 정리합니다.

드디어 마지막 챕터까지 와서 기뻐했건만, 정규표현식을 만나고 보스를 만난 기분입니다.

(제가 깨본 보스맵은 방구대장 뿡뿡이 CD게임과 보글보글 시리즈 뿐...)

정규 표현식 시리즈

1️⃣ 정규표현식이란? 문자 클래스, Dot(.), 반복(*), 반복(+), 반복({m,n}, ?)
2️⃣ 정규 표현식(2) - 문자열 검색(match, search, findall, finditer)
3️⃣ 정규표현식(3) - match 객체의 메서드(group, start, end, span)
4️⃣ 정규표현식(4) - COMPILE 옵션 - (DOTALL, IGNORECASE, MULTILINE, VERBOSE)
5️⃣ 정규 표현식(5) - 백슬래시 문제('\n')
6️⃣ 정규 표현식(6) 메타 문자 - |, ^, $, \A, \Z, \b, \B
7️⃣ 정규표현식(7) 그루핑, 전방 탐색, 문자열 바꾸기, Greedy vs Non-Greedy



7-1. 정규 표현식

정규 표현식(Regular Expressions)은 복잡한 문자열을 처리할 때 사용하는 기법입니다. 파이썬만의 고유 문법이 아닌 문자열을 처리하는 모든 곳에서 사용됩니다.

정규 표현식이 왜 필요한가요?

자. 아래와 같은 문제가 있다고 해봅시다.

task: 주민등록번호를 포함하고 있는 텍스트가 있다. 이 텍스트에 포함된 모든 주민등록번호의 뒷자리를 * 문자로 변경해 보자.

프로그램 작성 순서

  1. 전체 텍스트를 공백 문자로 나눈다(split).
  2. 나뉜 단어가 주민등록번호 형식인지 조사한다.
  3. 단어가 주민등록번호 형식이라면 뒷자리를 *로 변환한다.
  4. 나뉜 단어를 다시 조립한다.

정규 표현식 사용 전

data = """
park 800905-1049118
kim 700905-1059119
"""

# 결과를 담아줄 빈 리스트 생성
result = []

# 줄바꿈 되는 곳마다 split
for line in data.split('\n'):
    word_result = []
    # ' ' 공백마다 split
    for word in line.split(' '):
        # word의 길이가 14이면서, 앞 6자리와 뒤 7자리가 digit인 모든 조건을 만족하는
        if len(word) == 14 and word[:6].isdigit() and word[7:].isdigit():
            # word에 word에서 앞 6자리를 슬라이싱하여 '-'와 '*' 7개를 붙여준다.
            word = word[:6] + '-' + '*******'
        # for문 안에서 생성해둔 빈 리스트 word_result에 word 값을 담아준다.
        word_result.append(word)
    # result 에 word_result에 담긴 값을 ' ' 공백을 추가하여 담기
    result.append(' '.join(word_result))

# 다시 그 결과를 '\n' 줄 바꿈하여 출력
print('\n'.join(result))

# 결론: 복잡하다.
park 800905-*******
kim 700905-*******

정규 표현식 사용 후

import re

data = """
park 800905-1049118
kim 700905-1059119
"""

pat = re.compile("(\d{6})[-]\d{7}")
print(pat.sub("\g<1>-*******", data))
park 800905-*******
kim 700905-*******

정규 표현식을 사용하면 이렇게 간단해집니다. 아직 정규 표현식을 배우지 않았으니 코드를 이해하긴 어렵겠지만 대충 살펴보니 "" 큰 따옴표 안에 괄호(), 대괄호{}, d는 digit을 처리해주는 기호 같고, g는 뭘까요? 아무튼 눈으로 대강 훑어봅니다.👀


7-2. 정규 표현식 시작하기

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

# . ^ $ * + ? { } [ ] \ | ()

정규표현식에 사용되는 특별한 문자들입니다.

정규 표현식에 위의 메타 문자를 사용하면 특별한 의미를 갖게 됩니다. 하나씩 살펴보겠습니다.

(1) 문자 클래스 []

[] 사이의 문자들과 매치 라는 의미를 갖습니다. [abc]라면 이 표현식의 의미는 'a, b, c 중 한 개의 문자와 매치'된다는 의미입니다.

예시

정규식[abc]문자열매치 여부설명
[abc]a문자열 a와 매치⭕'a'는 정규식과 일치하는 'a'가 있으므로
before문자열 before과 매치⭕'before'은 정규식과 일치하는 'b'가 있으므로
dude문자열 dude와 매치 ❌'dude'는 정규식과 일치하는 문자 어떤 것도 없으므로

주의할 것: '^'

문자 클래스 안에 ^ 메타 문자를 사용할 경우엔 반대(not)의 의미를 갖습니다. 예를 들어, [^0-9]는 숫자가 아닌 문자만 매치됩니다.

자주 사용하는 문자 클래스

정규 표현식설명
\d숫자와 매치, [0-9]와 동일한 표현식
\D숫자가 아닌 것과 매치, [^0-9]와 동일한 표현식
\swhitespace 문자(space나 tab처럼 공백을 표현하는 문자와 매치, [ \t\n\r\f\v]와 동일한 표현식. 맨 앞은 공백을 의미한다.
\Swhitespace 문자가 아닌 것과 매치. [^ \t\n\r\f\v]
\w문자+숫자(alphanumeric)와 매치, [a-zA-Z0-9_]와 동일한 표현식이다.
\W문자+숫자(alphanumeric)가 아닌 문자와 매치, [^a-zA-Z0-9_]와 동일한 표현식이다.


(2) Dot(.)

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

다음 정규식을 봅시다.

a.b 👈 a와 b 사이에 줄바꿈 문자를 제외한 어떤 문자가 들어가도 모두 매치됨!

위 정규식의 의미는 아래와 같습니다.

"a + 모든 문자 + b"

즉, a와 b라는 문자 사이에 어떤 문자가 들어가도 모두 매치된다는 의미이다.

정규식[a.b]문자열매치 여부설명
[a.b]aab매치⭕'aab'는 가운데 문자 'a'가 모든 문자를 의미하는 .과 일치하므로 정규식과 매치
a0b매치⭕'a0b'는 가운데 문자 '0'이 모든 문자를 의미하는 .과 일치하므로 정규식과 매치
abc매치❌'abc'는 'a' 문자와 'b'문자 사이에 어떤 문자라도 하나 있어야 한다는 정규 표현식과 일치하지 않으므로 매치되지 않는다.

다음 정규식을 봅시다.

a[.]b 👈 a와 b 사이에 Dot(.) 문자가 있으면 매치!

이게 무슨 소리일까요?

위의 정규식 a[.]b는 "a.b" 문자열과 매치되지만, "a0b"와는 매치되지 않습니다.

문자 클래스 안의 . 이 사용된 형식([.])이라면 이것은 '모든 문자'가 아닌 문자 .의 있는 그대로를 의미하니 주의합니다!



(3) 반복(*)

ca*t

👉 * 옆에 있는 a가 0번 이상 반복되면 매치

이 정규식에서 는 반복을 의미한다. 바로 옆에 있는 문자 a가 0부터 무한대로 반복할 수 있다는 의미이다.

정규식문자열매치 여부설명
ca*tct매치⭕'a'가 0번 반복되어 매치
cat매치⭕'a'가 1번 반복되어 매치
caaat매치⭕'a'가 3번 반복되어 매치


(4) 반복(+)

ca+t

반복을 나타내는 +도 있다. + 는 최소 1번 이상 반복될 때 사용한다.

  • *: 0번부터 무한대로 반복
  • +: 최소 1번부터 무한대로 반복
정규식문자열매치 여부설명
ca+tct매치❌'a'가 0번 반복되어 매치되지 않음
cat매치⭕'a'가 1번 이상 반복되어 매치
caaat매치⭕'a'가 3번 이상 반복되어 매치


(5) 반복({m,n},?)

여기서 배우는 것은 반복 횟수를 지정해주고 싶을 때이다. 최소 1번 이상 3번 이하의 수를 반복하고 싶을 수 있다. 그럴 땐 {1,3}으로 표현이 가능하다.

이럴 때 { }를 사용하고 반복 횟수 고정이 가능하다. 만약 {3,}이면 반복 횟수가 3번 이상인 경우이며, {,3}일 때는 반복 횟수가 3 이하를 의미한다.

생략된 m은 0, 생략된 n은 무한대를 의미한다.

1) {m}

ca{2}t

위 정규식의 의미는 오른쪽과 같고, 정규식에 대한 매치 여부는 다음 표와 같다.

"c+a{반드시 2번 반복}+t"

정규식문자열매치 여부설명
ca{2}tcat매치❌'a'가 1번만 반복되어 매치되지 않음
caat매치⭕'a'가 2번 반복되어 매치

2) {m,n}

cat{2,5}t

👉 a가 2~5번 반복되면 매치

"c+a(2~5번 반복)+t"

정규식문자열매치 여부설명
ca{2,5}tcat매치❌'a'가 1번만 반복되어 매치되지 않음
caat매치⭕'a'가 2번 반복되어 매치
caaaaat매치⭕'a'가 5번 반복되어 매치

3) ?

ab?c

👉 b가 0~1번 사용되면 매치

"a+b(있어도 되고 없어도 된다)+c"

개인적으로 있어도 되고 없어도 된다는게 '?' 자체를 의미하는 것 같아서 슬프네요. (과몰입)

정규식문자열매치 여부설명
ab?cabc매치⭕'b'가 1번만 사용되어 매치
ac매치⭕'b'가 0번 반복되어 매치


반복 메타 문자

, +, ? 메타 문자는 모두 {m,m} 형태로 고쳐 쓰는 것이 가능하지만 가급적 이해하기 쉽고 표현도 간결한 , +, ? 메타 문자를 사용하는 것이 좋습니다.

profile
미남이 귀엽죠
post-custom-banner

0개의 댓글