본 포스팅은 충남대 이종률 교수님의 강의자료를 바탕으로 작성한 글입니다.
정규표현식은 어떤 문장에서 특정한 형태의 문자열을 뽑고 싶을 때 사용하는 것이다.
여러 방식이 있으니, 추출하려는 문자열의 특징을 잘 파악해서 사용해야 한다.
[표 정리]
/ | /Re pattern/ |
[abcd] | 대괄호 안의 문자들 중 하나 |
+ | + 앞의 문자를 하나 이상 |
g | Globally match |
^ | ^ 뒤의 문자로 시작되는 문자열 |
$ | $ 앞의 문자로 끝나는 문자열 |
? | ? 앞의 문자가 하나 또는 없음 |
* | * 앞의 문자가 없거나 그 이상 |
a|b | a 또는 b |
() | ()안의 문자들을 그룹으로 처리 |
()() | 괄호 그룹의 집합 |
. | 어떤 문자든 하나 |
\s | 공백 |
\S | 공백 아닌 문자 |
[^abcd] | abcd가 아닌 |
[a-z0-9가-힣] | 저 범위의 문자들 |
[실습]
이런 다양한 정규표현식을 사용하려면, re라는 라이브러리를 import해야하고,
re.search()와 re.findall()을 사용할 수 있다.
search() : 매칭에 성공한 첫 번째 문자열만 반환.
findall() : 매칭에 성공한 모든 문자열 반환.
if line.find('abc:')>=0:
if re.search('abc:', line):
if line.startswith('abc:'):
if re.search('^abc:', line):
re.search는 True나 False값을 반환한다.
re.findall은 찾은 모든 문자열들의 위치를 반환한다.
근데 여기서 찾을 때, 이 반복 문자들(*, +)는 가~장 긴 문자열과 매치되기 위해 양방향에서 바깥쪽으로 푸시한다.
예를 들어,
x = 'From: Using the : character'
y = re.findall('^F.+:', x)
print(y)
['From: Using the :']
이렇게, From:이 아니라 From: Using the :가 찾아진다는 점!
그치만, +, *와 함께 ?를 쓰게 된다면 얘기가 달라진다.
x = 'From: Using the : character'
y = re.findall('^F.?+:', x)
print(y)
['From:']
이렇게 greedy가 아닌 반환값을 찾게 된다.
그리고.. 이 괄호가 조금 특별한데,
x = From dabin.cnu@naver.com Sat Jan 5 09:00:00
y = re.findall('\S+@\S+', x)
print(y)
>> ['dabin.cnu@naver.com']
y = re.findall('^From (\S+@\S+)', x)
print(y)
>> [dabin.cnu@naver.com']
요렇게, 두 번째 코드에서 findall 시행시 From dabin.cnu@naver.com이 매칭은 되지만, y라는 변수에 추출되는 문자열은 dabin.cnu@naver.com이라는 괄호 안의 정규표현식에 해당하는 값이다.
이건 왜 쓰냐..? 라 한다면,
내가 여러 편지를 받았는데, 다들 From 00 이렇게 썼다.
근데 내가 원하는 건 From 00이 아니라 저 이름만 추출하기 원하는 것이다.
그럼 저렇게 From 까지 매칭을 우선 해놓고, 내가 필요한 변수에 저장할 땐 괄호 안의 내용만 저장하면 되는 것!
ex) re.findall('@([^ ]*)', x) 라고 되면, x가 이메일 주소라고 할 때, 도메인 즉 naver.com이나 daum.net같은 것만 추출되는 것임!
그리고 또 예시를 들자면, 어떤 데이터 내에서도 이렇게 사용할 수 있다.
만약에 구글폼으로 학과 전원의 키를 조사했다. 근데 이 중에 최댓값을 찾고 싶다면?
hand = open('height.txt')
numlist = list()
for line in hand:
line = line.rstrip()
stuff = re.findall('^your height : ([0-9.]+)', line) #키는 소숫점값으로 쓸 수도 있으니 0-9 또는 .을 하나 이상!
if len(stuff) != 1:
continue
num = float(stuff[0])
numlist.append(num)
print('Max height :', max(numlist))
이렇게 하면 된단 말씀!
그리고, 만약 위에 표에 있던 특수기호들을 저 의미가 아니라 진짜 찾고 싶다면?
\$ 처럼 앞에 역슬래시를 붙이면 된당.
'AI > 데이터과학' 카테고리의 다른 글
분류(K-Means, Agglomerative Clustering, DBSCAN) (3) | 2024.10.21 |
---|---|
Association Rule Mining (0) | 2024.10.21 |
상관관계 분석과 가설 검정 (0) | 2024.10.21 |
EDA의 일부, 데이터 전처리와 특성 추출 (2) | 2024.10.19 |
데이터 시각화 (0) | 2024.10.19 |