choosunsick.github.io

여러가지 데이터를 다룰 때 숫자와 더불어 문자열 데이터를 분석하거나 전처리 해야하는 경우가 종종 생기게 됩니다. 이런 문자열 데이터는 단순하게 다룰 수 있는 경우도 있지만 조건이 까다롭거나 다루는 과정에서 시간이 오래 걸리거나 원하는 결과를 제대로 산출하지 못하는 경우가 생길 수 있습니다. 예를 들면, 복잡한 문자열 데이터 사이에서 특정한 문자만 검색하거나 해당 문자를 제거하거나 변경하는 경우가 그렇습니다. 그런 상황에서 편리하게 사용할 수 있는 것이 바로 정규표현식입니다. 프로그래밍 언어마다 정규표현식을 다루는 방식은 차이가 존재하지만 문자열 데이터를 더 쉽게 다룰 수 있게 해준다는 것은 사실입니다. 그래서 이번에 정규표현식을 공부하면서 헷갈렸던 개념들을 정리해볼까 합니다.

* 와 ? 패턴

정규표현식은 패턴을 통해 문자열 데이터를 더 쉽게 다룰 수 있게 만들어 줍니다. 정규표현식에는 다양한 패턴들이 있습니다. 여기서 살펴볼 패턴은 문자의 개수와 관련있는 패턴인 *? 입니다. 먼저 * 패턴은 특정한 문자나 패턴 뒤에 붙여 사용하는 것으로 해당 문자가 최소 0번에서 n번 나타나는 것을 의미합니다. ? 패턴 역시 마찬가지 특정한 문자나 패턴 뒤에 붙여서 사용하는 것으로 해당 문자가 최소 0번에서 최대 1번 나타나는 것을 의미합니다.

이제 두 패턴에 대해 파이썬 예제를 통해 비교해보겠습니다.

import re

t = "http://www.forta.com/, httpa://www.forta.com/, https://www.forta.com/, httpsss://www.forta.com/"
print(re.findall("https*:\/\/[\w.]+",t))
print(re.findall("https?:\/\/[\w.]+",t))

파이썬은 정규표현식을 re 라는 패키지를 통해 다룹니다. re 패키지는 기본 패키지로 바로 import 할 수 있습니다. 예시 문자열 데이터로는 여러 개의 http 혹은 https와 유사한 문자열이 있는 경우를 가정해보겠습니다. 먼저 http인 경우와 https인 경우 그리고 http 뒤에 s가 아닌 다른 문자가 오는 경우 http 뒤에 s가 왔지만 하나가 아닌 경우 4가지 예시 문자열이 있습니다. 여기서 찾고 싶은 문자열 데이터는 정상적인 URL인 http와 https인 경우입니다. 이 두 가지 문자열을 찾을려면 * 이 아닌 ? 패턴을 사용해야 합니다.

먼저 * 패턴이 사용되는 경우 결과를 살펴보면 아래의 첫 번째와 같습니다. 첫 번째 결과물에는 s가 하나가 아닌 경우가 포함되어 있습니다. 왜냐하면 * 패턴의 경우 해당 문자가 최대 n번의 경우까지 포함하여 매칭하기 때문입니다. 반면 ? 패턴의 경우 우리가 원하는 문자열 2가지만 추출할 수 있습니다. ? 패턴은 최대 1번까지 나타나는 것을 매칭하기 때문에 s가 2번 이상 나오는 경우인 ‘httpsss://www.forta.com/’ 문자열은 제외하게 됩니다. 따라서 s가 0개인 ‘http://www.forta.com/’와 s가 1개인 경우 ‘https://www.forta.com/’ 두 가지만 추출하게 됩니다.

['http://www.forta.com/', 'https://www.forta.com/', 'httpsss://www.forta.com/']
['http://www.forta.com/', 'https://www.forta.com/']

그렇다면 만약 http 문자 뒤에 s가 아닌 다른 문자가 오는 경우를 포함해야한다면 어떻게 해야할까요 ? 기존의 *? 패턴 앞에 .을 추가해주면 됩니다.

t = "http://www.forta.com/, httpa://www.forta.com/, https://www.forta.com/, httpsss://www.forta.com/"
print(re.findall("http.*:\/\/[\w.]+",t))
print(re.findall("http.?:\/\/[\w.]+",t))

.* 패턴은 http 뒤에 아무 문자가 최소 0개에서 n개까지 오는 경우를 의미합니다. http 문자 뒤에 아무 문자가 최소 0개에서 n개까지 올 수 있기 때문에 4가지의 모든 경우가 다 나타날 수 있습니다. .? 패턴은 http 뒤에 아무 문자가 최소 0개에서 최대 1개까지 오는 경우를 의미합니다. 이에 따라 기존 ? 패턴에 http 문자 뒤에 s가 아닌 a가 오는 경우까지 포함하게 됩니다.

['http://www.forta.com/, httpa://www.forta.com/, https://www.forta.com/, httpsss://www.forta.com']
['http://www.forta.com', 'httpa://www.forta.com', 'https://www.forta.com']

정리하자면, 문자 뒤에 * 패턴이 붙는다면 그 특정문자가 0개에 n개인 경우가 포함되고, ? 패턴이 붙는다면 특정문자가 0개에서 1개까지인 경우가 포함됩니다. 문자 뒤에 .* 이 붙는다면 그 문자 뒤에 해당 특정문자가 아닌 아무 문자가 0개에서 n개 나오는 경우가 됩니다. 마찬가지로 문자 뒤에 .? 의 패턴이 붙는다면 아무 문자가 와도 상관 없지만 그 문자의 개수가 0개에서 1개까지 오는 경우가 됩니다.