Skip to content

Latest commit

 

History

History
194 lines (132 loc) · 7.18 KB

File metadata and controls

194 lines (132 loc) · 7.18 KB

정규표현식 (Regular Expression)

정규식은 문자열의 패턴을 표현하는 간단한 언어입니다. 정규식은 웹페이지에서 특정 정보를 선별하여 추출하는 경우 뿐 아니라, 문서 편집기 등에서 특정 패턴의 문자열을 찾거나 바꿀 때도 사용할 수 있습니다.

정규식의 간단한 예를 살펴봅시다.

abc.txt
hello.txt
notepad.exe

위와 같은 파일 이름을 정규식으로 표현하면 다음과 같습니다.

.*\.txt

위 정규식에서 . 은 하나의 아무 글자를 나타내고, * 은 그 글자가 여러개 올 수 있다는 것을, \. 은 마침표(.)를 나타내고, txt 는 문자 그대로입니다. 다시 말해, 아무 글자나 여러개 나타나고, 그 뒤에 .txt 라는 글자가 오는 문자열을 뜻합니다.

http://regexpal.com/

문자 표현자

[] 는 하나의 문자를 나타내지만, [] 사이에 표시한 문자만을 지칭하도록 한정합니다.

[fc]ord

위의 정규식은 아래와 같은 두 개의 문자열을 지칭합니다.

ford
cord

[^] 은 하나의 문자를 나타내지만, [^] 사이에 표시한 문자는 제외하도록 한정합니다.

. 는 아무 하나의 문자를 나타냅니다.

.ord

위의 정규식은, 첫 자리에 모든 문자를 허용합니다.

aord
bord
cord
dord
1ord
...

횟수 표현자

  • +: 해당 문자가 1회 이상 반복될 수 있음
  • *: 해당 문자가 없을 수도 있고 1회 이상 반복될 수 있음
  • ?: 해당 문자가 없을 수도 있고 1회 존재할 수 있음
  • {m}: 해당 문자가 m번 반복됨
  • {m,}: 해당 문자가 m회 이상 반복됨
  • {m,n}: 해당 문자가 m회 이상, n회 미만 반복됨
  • 횟수 표현자 뒤의 ?: minimal matching을 하도록 함.

위의 문자들은, 특정 문자나 식의 뒤에 쓰여서, 해당 요소의 반복 횟수를 표현하는 역할을 합니다.

h+ello

위의 정규식은 아래와 같은 문자열을 지칭합니다.

hello
hhello
hhhello

위치 표현자

정규식의 맨 앞에 쓰이는 ^ 표시는, 행의 첫 부분을 나타냅니다. 정규식의 맨 뒤에 쓰이는 $ 는 행의 맨 뒷부분을 나타냅니다.

기호

  • \d: 하나의 숫자를 표시합니다. 같은 표현으로 [0-9] 를 사용할 수도 있습니다.
  • \s: 하나의 공백을 표시합니다. (줄 바꿈 포함.) 같은 표현으로 [ \t\n] 을 사용할 수도 있습니다.

그룹

() 사이에 있는 문자열은 나중에 불러서 사용할 수 있습니다. 첫번째 그룹은 \1, 두번째 그룹은 \2 로 지칭합니다.

(BGM) 한밤에 미쳐서 올라프 만들기 (추가) | Sebastian's Tavern by 세바스찬 | 02/09 04:21
게임심의, 무엇이 문제인가? | WeissWine Workshop and Icecube S3 by 잼아줌마 | 02/09 06:53

위의 문자열에서 글 제목, 블로그 제목, 사용자 이름, 글 쓴 날짜를 추출하는 정규식은 다음과 같습니다.

(.+)\s\|\s(.+)\sby\s(.+)\s\|\s(.+)$

위의 정규식을 Python 코드로 표현하면 다음과 같습니다.

import re

pattern = re.compile(r'(.+)\s\|\s(.+)\sby\s(.+)\s\|\s(.+)$')

lines = ["(BGM) 한밤에 미쳐서 올라프 만들기 (추가) | Sebastian's Tavern by 세바스찬 | 02/09 04:21",
         "게임심의, 무엇이 문제인가? | WeissWine Workshop and Icecube S3 by 잼아줌마 | 02/09 06:53"]

for line in lines:
    matches = pattern.match(line) # 패턴과 매치하는지 점검
    if not matches:             # 매치하지 않는다면 건너뛴다
        continue

    print('Title:', matches.group(1))
    print('Blog:', matches.group(2))
    print('Writer:', matches.group(3))
    print('Date:', matches.group(4))
Title: (BGM) 한밤에 미쳐서 올라프 만들기 (추가)
Blog: Sebastian's Tavern
Writer: 세바스찬
Date: 02/09 04:21
Title: 게임심의, 무엇이 문제인가?
Blog: WeissWine Workshop and Icecube S3
Writer: 잼아줌마
Date: 02/09 06:53

Python에서 정규식을 표현할 때는, 문자열 앞에 r 을 붙이면 편리합니다. r 은 raw라는 뜻으로, 일반적인 문자열에서는 \ 를 이스케이프 특수 문자로 인식하는데, raw text에서는 이스케이프 문자로 인식하는 대신 그대로 \ 문자로 처리합니다. 만약 일반 문자열을 사용한다면 위의 코드에서 \ 대신 \\ 를 사용해야 합니다.

match 실행 결과로 나온 matcher 객체의 group 메소드를 사용해서 각 그룹에 해당하는 문자열을 추출해낼 수 있습니다.

HTML 요소를 처리하다 보면 문자열이 여러 줄에 걸쳐 있는 경우가 있습니다. 그럴 때는 MULTILINE 플래그를 써줘야 합니다.

pattern = re.compile("(.+)\s\|\s(.+)\sby\s(.+)\s\|\s(.+)$", re.M)

연습문제

아래는 논문에 포함되어 있는 레퍼런스 서지 정보입니다. 정규식을 사용해서, 저자 이름, 출판연도, 아티클 이름을 구별하여 추출해보세요.

Beare, B. (2017). The Chang-Kim-Park model of cointegrated density-valued time series cannot accommodate a stochastic trend. Econ Journal Watch 14, 133137.
Beare, B., J. Seo, and W. Seo (2017). Cointegrated Linear Processes in Hilbert Space. Journal of Time Series Analysis 38, 10101027.
Chang, Y., C. Kim, and J. Park (2016). Nonstationarity in time series of state densities. Journal of Econometrics 192, 152  167.