[Python] 정규 표현식(RegExp)

2024. 6. 13. 09:00·Programming Language/Python

정규표현식(Regular Expression)

  • 정규 표현식이란 문자열을 처리하는 방법 중의 하나로 특정한 조건의 문자를 ‘검색’하거나 ‘치환’하는 과정을 매우 간편하게 처리할 수 있도록 하는 수단
  • Python 뿐만 아니라 문자열을 처리하는 모든 곳에 사용됨

정규 표현식의 특징

  • 대소문자 구분
  • 띄어쓰기 수 구분

정규표현식의 필요성

  • 정규 표현식을 이용하면 직관적이고 간편한 코드를 짤 수 있고 복잡한 문자열의 규칙 등을 쉽게 치환할 수 있음
  1. 유효성 검사를 할 수 있음
  2. 정규표현식을 사용하면 특정 패턴이나 형식에 따라 입력 문자열의 유효성을 검사하여 이메일 주소, 전화번호 등이 예상 구조 및 형식을 따르는지 확인할 수 있으므로 작업 중인 데이터의 정확성과 무결성을 보장하는데 도움이 됨
  3. 패턴을 통해 데이터 추출 및 변환 가능
  4. 정규 표현식은 패턴을 정의하고 텍스트 내에서 일치 항목을 검색하는 간결하고 표현적인 구문을 제공하므로 여러 문자열 작업을 수행하거나 메타문자, 문자 클래스 등을 사용하여 복잡한 패턴을 지정할 수 있음. 또한 특정 패턴을 통해 복잡한 패턴을 쉽게 찾을 수 있으며, 데이터를 원하는 형식이나 구조로 변환할 수 있도록 도와줌

정규 표현식 메타문자

1) 문자 클래스, [ ]

  • 문자 클래스인 []는 "[] 사이의 문자들과 매치"라는 의미를 가지며, []사이에는 어떤 문자도 들어갈 수 있음
    • [abc]  = "a, b, c 중 한 개의 문자와 매치"
  • 예시) [abc] 와 "a", "before", "dude"
    • a는 정규식과 일치하는 문자인 a가 있으므로 매치
    • before는 정규식과 일치하는 문자인 b가 있으므로 매치
    • dude는 정규식과 일치하는 문자인 a, b, c중 어느 하나도 포함하고 있지 않으므로 매치되지 않음

2) 하이픈(-), 캐럿(^)

  • 하이픈(-)은 두 문자 사이의 범위(from - to)를 의미, 캐럿(^)은 반대를 의미
    • [a-zA-Z]: 알파벳 모두 매치
    • [0-9]: 숫자 매치
    • [^0-9]: 숫자가 아닌 문자만 매치
      • []안에서는 부정의 의미로 사용
      • []가 없으면 문자열의 처음을 뜻함(끝은 $로 표시)
  • 문자클래스[]안에는 어떤 문자나 메타 문자도 사용할 수 있지만 ^는 반대(not)의 의미로 사용되기 때문에 조심해야함

3) \(역슬래쉬)

  • [0-9]또는 [a-zA-Z]와 같은 정규표현식은 \역슬래쉬를 이용해 간단하게 표현할 수 있음

자주 사용하는 문자 클래스

  • [0-9] → 숫자와 매치, \d
  • [^0-9] → 숫자가 아닌 것과 매치, \D
  • [ \t\n\r\f\v] → whitespace 문자와 매치(맨 앞의 빈칸은 공백문자(space)를 의미, \s
  • [^ \t\n\r\f\v] → whitespace 문자가 아닌 것과 매치, \S
  • [a-zA-Z0-9_] → 문자 + 숫자와 매치, \w
  • [^a-zA-Z0-9_] → 문자+숫자가 아닌 문자와 매치, \W

Dot(.)

  • 줄바꿈 문자인 \\n을 제외한 모든 문자와 매치됨을 의미
  • a.b → 정규식의 의미는 "a + 모든문자 + b"와 같음
  • 즉 a와b라는 문자 사이에 어떤 문자가 들어가도 모두 매치가 된다는 의미
    • 예시) "aab", "a0b", "abc"
      • aab는 가운데 문자 a가 모든 문자를 의미하는 .과 일치하므로 정규식과 매치됨
      • a0b도 동일하게 가운데 문자 0이 모든 문자를 의미하는 .과 일치하므로 정규식과 매치됨
      • abc는 a와 b사이에 어떤 문자가 존재하지 않기 때문에 위 정규식과 매치되지 않음

+ ? {} (반복 관련 메타 문자)

  • 반복 (*)
    • 메타문자 * 은 * 바로 앞에 있는 문자가 0부터 무한대로 반복될 수 있다는 의미

ca*t -> c + a(0번 이상 반복) + t

  • ct → Yes → a가 0번 반복되어 매치
  • cat → Yes → a가 0번 이상 반복되어 매치(1번 반복)
  • caaat → Yes → a가 0번 이상 반복되어 매치(3번 반복)
  • ct, cat, caaaat 모두 매치됨
  • 반복 (+)
    • +는 * 과 달리 최소 1번 이상 반복될 때 사용
    • 즉 *은 반복횟수가 0부터 시작, +는 반복횟수가 1부터 시작

ca+t

  • c + a(1번 이상 반복) + t
  • ct → No → a가 0번 반복되어 매치되지 않음
  • cat → Yes → a가 1번 이상 반복되어 매치(1번 반복)
  • caaat → Yes → a가 1번 이상 반복되어 매치(3번 반복)
  • ct, cat, caaat중 ct는 매치되지 않음
  • 반복 ({m,n})
    • {}는 원하는 반복횟수를 지정하고 싶을 때 사용. m에서 n까지 반복, m이상인 경우, n이하인 경우 등 자유롭게 원하는 만큼 조절이 가능
      1. {m}: 반드시 m번 반복
        • ca{2}t: “c + a(반드시 2번 반복) + t”
      2. {m, n}: m~n회 반복
        • ca{2, 5}t: “c + a(2~5회 반복) + t”
      3. {m,}, {,n}: m회 이상 반복, n회 이하 반복
  • 반복(?)
    • ?는 반복은 아니지만 비슷한 개념으로 {0, 1}과 같은 의미를 지님. 즉, 문자가 있거나 없거나 둘 다 매치 되는 경우
    • ab?c : “a + b(있어도 되고 없어도 된다) + c”
  • *, +, ?메타 문자는 모두 {m, n} 형태로 고쳐 쓰는 것이 가능하지만 가급적 이해하기 쉽고 간결한 *, +, ?메타 문자를 사용하는 것이 좋음

파이썬 정규표현식

파이썬은 정규표현식을 지원하기 위해 re(regular expression) 모듈 제공

import re
pattern = re.compile("정규식")

re.compile을 사용하여 정규 표현식을 컴파일

re.compile의 결과인 객체 pattern에 입력한 정규식의 대한 정보가 담겨있음

 

ex) 이 코드를 실행해 생성된 객체 p로 메서드 살펴보기

import re
p = re.compile('[a-z]+')
  • match()
    • 문자열의 처음부터 정규식과 매치되는지 조사
m = p.match("python")
print(m)

→ python문자열은 [a-z]+정규식에 부합되므로 match 객체를 돌려줌

p = re.compile(정규표현식)
m = p.match(문자열)

if m:
    print("정규식 일치")
else:
    print("정규식 불일치")
  • search()
    • 문자열 전체를 검색하여 정규식과 매치되는지 조사
m = p.search("3 python")
print(m)

→ 3 python문자열은 첫번째 문자가 숫자이므로 match메서드에서는 None을 반환합니다. 하지만 search메서드는 문자열의 처음부터 검색하는 것이 아니라 문자열 전체를 검색하기 때문에 “python”문자열과 매치돼서 match객체를 반환

  • findall()
    • 정규식과 매치되는 모든 문자열을 리스트로 돌려줌
    result = p.findall("life is too short")
    print(result)
    
    → 정규식과 일치하는 부분인 각 단어들이 반환되는 것을 확인할 수 있음
  • finditer()
    • 정규식과 매치되는 모든 문자열을 반복 가능한 객체로 돌려줌
    result = p.finditer("life is too short")
    print(result)
    
    → 반복 가능한 객체가 포함하는 각각의 요소는 match 객체

match 객체의 메서드

  • group()
    • 매치된 문자열 돌려줌
  • start()
    • 매치된 문자열의 시작 위치를 돌려줌
  • end()
    • 매치된 문자열의 끝 위치를 돌려줌
  • span()
    • 매치된 문자열의 (시작, 끝)에 해당하는 튜플을 돌려줌
m = p.match("python")
print('매치된 문자열 : ', m.group())
print('매치된 문자열의 시작 위치 : ', m.start())
print('매치된 문자열의 끝 위치 : ', m.end())
print('매치된 문자열의 (시작, 끝) : ', m.span())

m = p.search("3 python")

print('매치된 문자열 : ', m.group())
print('매치된 문자열의 시작 위치 : ', m.start())
print('매치된 문자열의 끝 위치 : ', m.end())
print('매치된 문자열의 (시작, 끝) : ', m.span())

축약된 형태
>>> m = re.match('[a-z]+', "python")

컴파일 옵션

  • DOTALL(S) - . 이 줄바꿈 문자를 포함하여 모든 문자와 매치할 수 있도록 함
  • IGNORECASE(I) - 대소문자에 관계없이 매치할 수 있도록 함
  • MULTILINE(M) - 여러줄과 매치할 수 있도록 함(^, $ 메타문자의 사용과 관계가 있는 옵션)
  • VERBOSE(X) - verbose 모드를 사용할 수 있도록 함(정규식을 보기 편하게 만들수 있고 주석 등을 사용할 수 있게됨)

→ 옵션을 사용할 때는 re.DOTALL처럼 전체 옵션이름을 써도 되고, re.S처럼 약어를 써도 됨

DOTALL, S

.메타 문자가 줄바꿈 문자\\n도 포함시키도록 하고 싶다면 re.DOTALL또는 re.S옵션을 사용해 정규식을 컴파일하면 됨

p = re.compile('a.b', re.DOTALL)
m = p.match('a\\nb')
print(m)

→ re.DOTALL옵션으로 \\n도 매치시키는 것을 확인할 수 있음

IGNORECASE, I

re.IGNORECASE 또는 re.I 옵션은 대소문자 구별 없이 매치를 수행할 때 사용하는 옵션

p = re.compile('[a-z]', re.I)
p.match('python')

→ [a-z] 정규식은 소문자만을 의미하지만 re.I옵션으로 대소문자 구별없이 매치되는 것을 볼 수 있음

MULTILINE, M

^은 문자열의 처음, $은 문자열의 마지막을 의미

import re
p = re.compile("^python\\s\\w+")

data = """python one
life is too short
python two
you need python
python three"""

print(p.findall(data))

→ 결과를 보면 알겠지만 ^메타 문자에 의해 python이라는 문자열을 사용한 첫 번째 줄만 매치

하지만 ^메타 문자를 문자열 전체의 처음이 아니라 각 라인의 처음으로 인식시키고 싶은 경우가 있을 것입니다. 이럴 때 사용하는 옵션이 바로 re.MULTILINE 옵션임

re.MULTILINE옵션을 추가

import re
p = re.compile("^python\\s\\w+", re.MULTILINE)

data = """python one
life is too short
python two
you need python
python three"""

print(p.findall(data))

→ 다음과 같이 ^메타 문자가 문자열의 각 줄마다 적용되는 것을 확인

VERBOSE, X

여태 봐왔듯이 정규식은 굉장히 가독성이 안좋은 것을 알 수 있습니다. 이런 정규식의 가독성을 조금이나마 해결해주기 위한 옵션이 바로 VERBOSE

charref = re.compile(r'&[#](0[0-7]+|[0-9]+|x[0-9a-fA-F]+);')

charref = re.compile(r"""
 &[#]                # Start of a numeric entity reference
 (
     0[0-7]+         # Octal form
   | [0-9]+          # Decimal form
   | x[0-9a-fA-F]+   # Hexadecimal form
 )
 ;                   # Trailing semicolon
""", re.VERBOSE)
print(p.findall(charref))

첫 번째와 두 번째 예를 비교해보면 패턴 객체인 charref는 모두 동일한 역할을 합니다. 하지만 두번째처럼 주석을 적고 여러 줄로 표현하는 것이 가독성이 좋은 것

→ re.VERBOSE옵션은 문자열에 사용된 whitespace가 컴파일시 제거되며, #을 이용해 주석문을 달 수 있음

저작자표시 비영리 변경금지 (새창열림)

'Programming Language > Python' 카테고리의 다른 글

[Python] 시각화할 때 한글 깨지는 경우  (0) 2024.06.13
[Python] Numpy(넘파이)  (0) 2024.06.13
[Python] Math.gcd - 최대공약수  (0) 2024.06.12
[Python] 내장 함수  (0) 2024.06.12
[Python] 제어문 & 반복문  (1) 2024.06.12
'Programming Language/Python' 카테고리의 다른 글
  • [Python] 시각화할 때 한글 깨지는 경우
  • [Python] Numpy(넘파이)
  • [Python] Math.gcd - 최대공약수
  • [Python] 내장 함수
woojin._.
woojin._.
여러가지 개발을 해보며 발생하는 이야기들에 대한 블로그입니다:)
  • woojin._.
    Jin's Dev Story
    woojin._.
  • 전체
    오늘
    어제
    • 분류 전체보기 (829)
      • Tools (25)
        • eGovFrame (3)
        • GeoServer (3)
        • QGIS (2)
        • LabelImg (2)
        • Git (6)
        • GitHub (1)
        • Eclipse (7)
        • Visual Studio (1)
      • Web & Android (121)
        • SpringBoot (37)
        • Three.js (2)
        • Spring Data JPA (9)
        • 스프링 부트 쇼핑몰 프로젝트 with JPA (25)
        • Thymeleaf (4)
        • Spring Security (15)
        • Flutter (29)
      • Programming Language (61)
        • JAVA (27)
        • JavaScript (14)
        • Dart (2)
        • Python (15)
        • PHP (3)
      • Database (43)
        • PostgreSQL (32)
        • MYSQL (7)
        • Oracle (3)
        • MSSQL (1)
      • SERVER (17)
        • TCP_IP (3)
        • 리눅스 (7)
        • AWS (7)
      • Coding Test (445)
        • 백준[JAVA] (108)
        • 프로그래머스[JAVA] (260)
        • 알고리즘 고득점 Kit[JAVA] (3)
        • SQL 고득점 Kit[ORACLE] (74)
      • CS 지식 (49)
        • [자료구조] (14)
        • [네트워크] (12)
        • [데이터베이스] (10)
        • [알고리즘] (9)
        • [운영체제] (4)
      • 기타 (6)
      • 자격증 & 공부 (62)
        • 정보처리기사 (2)
        • SQLD (6)
        • 네트워크관리사 2급 (5)
        • 리눅스마스터 1급 (44)
        • 리눅스마스터 2급 (1)
        • ISTQB (3)
        • 시스템보안 (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 인기 글

  • 태그

    DB
    CS
    플러터
    리눅스마스터
    programmers
    python
    pcce 기출문제
    Java
    Linux
    JPA
    CS지식
    스프링부트
    스프링
    자바
    리눅스
    Oracle
    backjoon
    postgresql
    Flutter
    데이터베이스
    데이터
    시큐리티
    springboot
    프로그래머스
    리눅스마스터 1급
    spring
    baekjoon
    Spring Security
    스프링 부트 쇼핑몰 프로젝트 with JPA
    백준
  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
woojin._.
[Python] 정규 표현식(RegExp)
상단으로

티스토리툴바