본문 바로가기
정보보안/Python

[Python] 정규 표현식 - re 모듈

by 용오동 2024. 12. 1.
반응형

 


♣ Python에서는 re 모듈을 통해 정규 표현식을 사용할 수 있다.

re 모듈의 함수를 호출하여 패턴에 일치하는 문자열을 검색하거나 치환하는 등 다양한 동작을 수행한다.

# python 정규 표현식을 활용한 코드 예제
# 문자열에서 알파벳 대문자만 출력

import re

pattern = re.compile("[A-Z]")
result = pattern.findall("Hello, My name is ODong!")

print(result)

# 결과 : ['H', 'M', 'O', 'D']

 

♣ re 모듈을 사용하는 순서

    1. re 모듈 import

import re

 

    2. 검색할 패턴을 생성하고 객체(변수)를 생성한다.

객체명(변수명) = re.compile("패턴")

 

    3. 객체를 이용하여 문자열을 검색한다.

        3-1 객체명.match("전체 문자열")

        > 전체 문자열이 패턴으로 일치하는지를 검색한다.(1개의 결과)

        > 결과 : <re.Match ...>

 

        3-2 객체명.search("전체 문자열")

        > 전체 문자열 내에서 패턴에 처음으로 매치하는 문자열을 검색한다.(1개의 결과)

        > 결과 : <re.Match ...>

 

        3-3 객체명.findall("전체 문자열")

        > 전체 문자열 내에서 패턴과 일치하는 모든 단어들을 찾아 리스트로 리턴(여러개의 결과)

        > 결과 : ['패턴1', '패턴2', '패턴3']

 

        3-4 객체명.finditer("전체 문자열")

        > 일치하는 모든 단어들을 찾아 객체들을 모아 리스트화한다. 즉, 모든 문자열 객체를 리스트 형식으로 반환한다.

        > 결과 : [<re.Match ...>, <re.Match ...>, <re.Match ...>, ...]

 

♣ match(문자열) : 전체 문자열의 시작이 패턴과 동일한지를 검색하는 함수이다. 최초로 발견된 1개만 리턴한다.

  • 무조건 처음부터 일치해야 한다.
  • match()를 이용하여 생성한 객체에 사용할 수 있는 메소드

        > group() : 객체에서 찾은 문자열을 리턴

        > span() : 전체 문자열에서 패턴이 발견된 시작 인덱스와 종료 인덱스를 리턴

        > start() : 패턴이 발견된 시작 인덱스를 리턴

        > end() : 패턴이 발견된 종료 인덱스를 리턴

  • <...>로 나오는 결과들은 객체를 의미한다.
  • start()와 end()는 시작 / 종료 인덱스를 따로 분리하기 위해 사용한다.

 

♣ search(문자열) : 전체 문자열 내에서 어디에서든지 패턴과 매치되는 문자열이 있으면 찾아낸다. 최초 발견된 1개만 리턴된다.

  •  어느 위치에서든지 일치하면 처음 발견된 1개만 찾아준다.
  • search()를 이용하여 생성한 객체에 사용할 수 있는 메소드

        > group(), span(), start(), end()

  • search()는 match()와 다르게 발견된 시작 위치도 알 수 있다.

 

♣ findall(문자열) : 전체 문자열 내에서 패턴과 매치되는 모든 문자열을 찾아 리스트로 리턴한다.

  • 일치하는 모든 패턴을 찾아 리스트로 리턴한다.

 

♣ 정규 표현식

정규 표현식은 '패턴' 혹은 /패턴/의 형태로 작성한다. /로 패턴을 감싸는 경우, / 뒤에 플래그를 작성할 수 있다.

  • 메타 문자 : 문자 그대로 해석되지 않고, 특별한 목적으로 해석되는 문자들을 말한다.
  • [] : 문자 클래스라 부르며, [] 안에 있는 각 개별적인 문자들을 or 연산으로 처리한다.
  • [^] : ^ 뒤의 패턴을 제외한 나머지와 매치한다.(not)
  • \d : 숫자 1문자를 매치한다.([0123456789] 또는 [0-9])
  • \D : 숫자가 아닌 1문자를 매치한다.([^0123456789] 또는 [A-Za-z~!@#$%^&*()_+|])
  • \w : 숫자, 알파벳(대소문자), _(언더바) 1문자를 매치한다. ID, 변수, DB 필드명 생성 규칙과 동일하다.([0-9A-Za-z_])
  • \W : 숫자, 알파벳(대소문자), _(언더바)를 제외한 1문자를 매치한다.([^ 0-9A-Za-z_])
  • \s : White Space(Space Bar, Enter, Tab) 1문자를 매치한다. 즉, 공백 문자와 매치한다.([\b\f\n\r\t\v])
  • \S : 공백 문자가 아닌 1문자를 매치한다.([^ \b\f\n\r\t\v])
  • * : 앞에 나온 문자가 0개 이상이면 매치한다.
  • + 앞에 나온 문자가 1개 이상이면 매치한다.
  • ? : 앞에 나온 문자가 0개 혹은 1개면 매치한다.
  • {n} : 앞에 나온 문자가 n번 반복되면 매치한다.
  • {n, } : 앞에 나온 문자가 n번 이상 반복되면 매치한다.
  • {n, m} : 앞에 나온 문자가 n번 이상 m번 이하 반복되면 매치한다.(단, n>m)
  • () : 괄호로 감싼 부분을 그룹화하여 하나의 문자처럼 여긴다.
import re

url1 = "http://www.ktword.co.kr/index.html"
url2 = "https://www.naver.com/search.html?s=secure"
url3 = "ftp://ftp.kaist.ac.kr"

pat = re.compile("https?://")

print(pat.match(url1))
print(pat.match(url2))
print(pat.match(url3))

# 결과
<re.Match object; span=(0, 7), match='http://'>
<re.Match object; span=(0, 8), match='https://'>
None

 

# Greedy 수량자 : 기본 정규 표현식의 수량자(*, +, ?, {n} 등)는 탐욕적(Greedy) 수량자에 속한다. 패턴에 더 이상 매치하지 않을 때까지 모두 매치하는 문자열로 인식한다.

# Lazy 수량자 : 기존 수량자의 뒤에 ?를 붙인 형태로, 가능한 적은 문자를 매치한다.

 

# 정규 표현식 플래그

정규 표현식의 플래그는 검색의 옵션을 지정하는 역할을 한다. 일반적으로 /패턴/플래그 형식으로 작성한다.

  • g : global search, 매치하는 모든 문자 또는 문자열을 검색한다.
  • i : ignore case, 대소문자를 구분하지 않고 검색한다.
  • m : multiline, 여러 줄에서 검색한다.
  • s : single line(dotall), 메타 문자 .가 개행 문자도 포함한다.

 

♣ 컴파일 옵션

python에서 정규 표현식을 컴파일할 때 다음 옵션을 사용할 수 있다.

  • IGNORECASE(I) : 대소문자에 상관 없이 매치될 수 있게 한다.
  • DOTALL(S) : .(dot)이 \n을 포함해 모든 문자와 매치될 수 있게 한다.
  • MULTILINE(M) : ^의 해석을 문자열의 매 행마다 해석한다.
  • VERBOSE(X) : verbose 모드를 사용할 수 있게 한다. 어려운 정규식을 주석/줄 단위로 구분되기 한다.

# 사용 방법 : re.DOTALL 또는 re.S

(여러 옵션을 사용할 때는 파이프(|)를 사용하면 된다.)

re.compile("패턴", re.IGNORECASE)

 

♣ 문자열의 소비가 없는 메타 문자

검색에는 활용하지만 검색 결과에는 포함되지 않는 메타 문자를 의미한다.

  • | : 단어단위로 or 연산을 한다.(A|B : A 또는 B)
  • ^ : 문자열의 시작 부분부터 검색한다.
  • $ : 문자열의 마지막과 일치하는지 검색한다.
  • \A : 문자의 시작 부분부터 검색한다. re.MULTILINE 옵션을 무시하고, 문자열의 첫 부분만으로 한정하여 검색한다.
    (re.MULTILINE 옵션을 사용하지 않는 ^와 동일하다.)
  • \Z : re.MULTILINE 옵션을 무시하고 문자열의 마지막 부분만으로 한정하여 검색한다.
    (re.MULTILINE 옵션을 사용하지 않는 $와 동일함)
  • \b : Word Boundary, 단어의 구분자이다. 검색하는 패턴의 앞/뒤 단어를 구분할 수 있는 띄어쓰기, 특수문자 등을 인식하여 검색할 때 사용한다.
  • \B : \b의 반대 개념으로, 화이트 스페이스(White Space)로 구분된 단어가 아닌 경우에만 매치된다.

 

♣ 그루핑(Grouping)

조회된 결과를 세분화하여 일부를 발췌하기 위해 샤용함

  • 메타문자 ()로 그룹을 나누며 나누어진 그룹 전체를 0번으로 시작하여 나눈 그룹에 순서가 매겨짐
  • 여러개의 그룹으로 나누어진 경우 괄호가 열린 순서대로 그루핑
  • 그루핑된 문자열 재참조 : 동일한 단어들이 반복되는 패턴을 찾고 싶을 때 사용한다. '\인덱스번호'로 사용한다.

 

    # 그루핑된 문자열에 이름 붙이기

       > 사용법 : (?P<그룹명>패턴)

       > 사용자가 원하는 이름을 부여하여 그루핑을 인덱스 대신 구별하여 사용할 수 있다.

        > 그룹을 추가할 경우 순서에 대해 생각하지 않아도 이름으로 바로 조회가 가능하다.

# 그루핑된 문자열에 이름 붙이기
(생략)
pat = re.compile(r"(?P<id>\w+)\s(?P<rrn>\d{6}-\d{7})")
print(match.group("id"), match.group("rrn"), sep = "/")

 

♣ Raw String(r-string)

Raw String은 문자열 앞에 'r'을 붙여 나타낸다. Raw String은 이스케이프 문자를 문자 그대로 인식하는 특수한 문자열이다. 정규 표현식 패턴을 작성할 때 백슬래쉬(\)가 이스케이프 문자로 해석되지 않도록 문자열 맨 앞에 r을 붙여 표현한다.

print("\t" + "Hi")
# 결과 :    HI

print(r"\t" + "Hi")
# 결과 :\tHi

 

♣ 전방 탐색(Lookahead assertions)

특정 문자로 끝나는 문자열을 검색하지만, 결과에는 특정 문자가 포함되지 않기를 원할 때 사용하는 기법

 

    # 긍정형 전방 탐색

        > 사용법 : (?=문자열)

        > 문자열에 해당하는 정규식과 매치되어야 하며, 조건이 통과되어도 문자열이 소비되지 않는다.

p = re.compile(".+(?=:)")
m = p.search("http://google.com")
print(m.group())

# 결과 : http

    # 부정형 전방 탐색

        > 사용법 : (?!문자열)

        > 문자열에 해당하는 정규식과 매치되지 않아야 하며 조건이 통과되어도 문자열이 소비되지 않는다.

 

문자열 바꾸기

  #  sub() : '원본 문자열'에서 "new문자열'로 바꾸는 메소드

        > 사용법 : pattern.sub('new문자열', '원본문자열', count = 수정횟수)

         (pattern = re.compile("패턴"))

p = re.compile("(blue|white|red)")
p.sub("color", "blue socks and red shoes")

# 결과 : 'color socks and color shoes'

 

  # subn() : 패턴과 일치하는 문자열을 'new문자열'로 수정 후 '수정된 문자열', 수정개수를 튜로 반환함

p = re.compile("(blue|white|red)")
p.subn("color", "blue socks and red shoes")

# 결과 : ('color socks and color shoes', 2)

♣ JavaScript 정규 표현식

JavaScript에서는 2가지의 방법으로 정규 표현식을 사용한다.

1. 정규 표현식 리터럴 : '/패턴/' 혹은 '/패턴/플래그'의 형태로 작성한다.

2. RegExp 객체 생성 : new RegExp(정규 표현식 리터럴, '플래그') 혹은 new RegExp('패턴', '플래그')로 객체를 생성한다.

 

♣ 정규 표현식 함수

    # pattern.exec(string) : 패턴에 처음으로 매치하는 문자열의 일치 정보를 나타내는 결과 배열을 반환한다.

    # pattern.test(string) : 패턴에 매치하는 부분이 있으면 true, 없으면 false를 반환한다.

    # string.match(pattern) : 패턴에 매치하는 모든 문자열을 배열 형태로 반환한다.

// 정규 표현식을 활용하여 전체 문자열에서 숫자만 출력
const r = new RegExp(/\d/, 'g');

const str = "H3ll0, DreamH4ck!";
const result = str.match(r);
console.log(result);

// 결과 : ['3', '0', '4']

★ 정규 표현식 연습 도구

 

RegExr: Learn, Build, & Test RegEx

RegExr is an online tool to learn, build, & test Regular Expressions (RegEx / RegExp).

regexr.com

 

Regexper

 

regexper.com

 

dreamhack-tools

 

tools.dreamhack.games

 


반응형