일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- numpy
- 스터디노트
- matplotlib
- 등차수열
- tree.fit
- 파이썬
- 자료구조
- Slicing
- barh
- SQL
- 순열
- INSERT
- pandas 메소드
- DataFrame
- MacOS
- pandas
- plt
- pandas filter
- 등비수열
- 통계학
- 재귀함수
- 기계학습
- 조합
- python
- 문제풀이
- Folium
- Machine Learning
- 머신러닝
- 리스트
- maplotlib
Archives
- Today
- Total
코딩하는 타코야끼
[Python] 11강_파이썬 정규표현식 본문
728x90
반응형
1. 정규 표현식(Regular Expression) 개요
📍 정규 표현식이란
- 텍스트에서 특정한 형태나 규칙을 가지는 문자열을 찾기 위해 그 형태나 규칙을 정의하는 것.
- 파이썬 뿐만 아니라 문자열을 다루는 모든 곳에서 사용된다.
- 정규식, Regexp이라고도 한다.
📍 기본개념
- 패턴
- 정규 표현식이라고 한다.
- 문장내에서 찾기위한 문구의 형태에 대한 표현식.
- 메타문자
- 패턴을 기술하기 위해 사용되는 특별한 의미를 가지는 문자
- 예) a* : a가 0회 이상 반복을 뜻한다. a, aa, aaaa
- 리터럴
- 표현식이 값 자체를 의미하는 것
- 예) a는 a 자체를 의미한다.
2. 정규 표현식 메타 문자
- 패턴을 기술하기 위한 문자
📍 문자 클래스 : [ ]
- [ ]사이의 문자들과 매칭
- [abc] : a, b, c 중 하나의 문자와 매치
- ``를 이용해 범위로 설정할 수 있다.
- [a-z] : 알파벳소문자중 하나의 문자와 매치
- [a-zA-Z0-9] : 알파벳대소문자와 숫자 중 하나의 문자와 매치
- [^ 패턴] : ^ 으로 시작하는 경우 반대의 의미
- [^abc] : a, b, c를 제외한 나머지 문자들 중 하나와 매치.
- [^a-z] : 알파벳 소문자를 제외한 나머지 문자들 중 하나와 매치
📍 미리 정의된 문자 클래스
- 자주 사용되는 문자클래스를 미리 정의된 별도 표기법으로 제공한다.
- \d : 숫자와 매치. [0-9]와 동일
- \D : \d의 반대. 숫자가 아닌 문자와 매치. [^0-9]와 동일
- \w : 문자와 숫자, _(underscore)와 매치. [a-zA-Z0-9_]와 동일
- \W : \w의 반대. 문자와 숫자와 _ 가 아닌 문자와 매치. [^a-zA-Z가-힣0-9_]와 동일
- \s : 공백문자와 매치. tab,줄바꿈,공백문자와 일치
- \S : \s와 반대. 공백을 제외한 문자열과 매치.
- \b : 단어 경계(word boundary) 표시. 보통 단어 경계로 빈문자열
- 단어경계: 단어(글자- \\w)와 단어가 아닌 문자사이를 가리킨다.
- \\b가족\\b => 우리 가족 만세(O), 우리가족만세 (X)
- \B : \b의 반대. 단어 경계로 구분된 단어가 아닌 경우
- \B가족\B => 우리 가족 만세(X), 우리가족만세 (O)
📍 글자수와 관련된 메타문자
- . : 한개의 모든 문자(\n-줄바꿈 제외) (a.b)
- `` : 앞의 문자(패턴)과 일치하는 문자가 0개 이상인 경우. (a*b)
- + : 앞의 문자(패턴)과 일치하는 문자가 1개이상인 경우. (a+b)
- ? : 앞의 문자(패턴)과 일치하는 문자가 한개 있거나 없는 경우. (a?b)
- {m} : 앞의 문자(패턴)가 m개. (a{3}b)
- {m,} : 앞의 문자(패턴)이 m개 이상. (a{3,}b)
- , 뒤에 공백이 들어오지 않도록 한다.
- {m,n} : 앞의 문자(패턴)이 m개이상 n개 이하. (a{2,5}b)
- ., ``, +, ? 를 리터럴로 표현할 경우 \\를 붙인다.
📍 문장의 시작과 끝 표현
- ^ 문자열의 시작 (^abc)
- 문자 클래스([ ])의 ^와는 의미가 다르다.
- $ : 문자열의 끝 (abc$)
📍 기타
- | : 둘중 하나 (OR) (010|011|016|019)
- 010|016-111 : 010 또는 016-111 이 된다.
- ( ) : 패턴내 하위그룹을 만들때 사용
3. re 모듈
- 파이썬에서 정규 표현식을 지원하기 위한 모듈
- 파이썬 기본 라이브러리
📍 코딩패턴
🌓 모듈 import
- import re
🌓 객체지향형
- 패턴 객체를 생성후 메소드를 호출해 원하는 처리를 한다.
🌓 함수형
- re 모듈의 원하는 작업을 하는 함수를 호출한다. Argument로 패턴과 처리할 값을 전달한다.
🌓 raw string
- 패턴문자중 \로 시작하는 것들을 사용할 경우 escape 문자와의 구분을 위해 \\ 두개씩 작성해야한다. 그래서 패턴을 지정할 때는 raw string을 사용하는 것이 편리하다.
- re.compile('\b가족\b') : \b를 escape 문자 b(백스페이스)로 인식
- re.compile(r'\b가족\b') : \b가 일반문자가 되어 컴파일시 정규식 메타문자로 처리된다.
📍 검색함수
- match(), search() : 패턴과 일치하는 문장이 있는지 여부를 확인할 때 사용
- findall() : 패턴과 일치하는 문장을 찾을 때 사용
🌓 Match 객체
- 검색 결과를 담아 반환되는 객체
- match(), search() 의 반환타입
- 패턴과 일치한 문자열과 대상문자열 내에서의 위치를 가지고 있는 객체
- 주요 메소드
- group() : 매치된 문자열들을 튜플로 반환
- group(subgroup 번호) : 패턴에 하위그룹이 지정된 경우 특정 그룹의 문자열 반환
- start(), end() : 대상 문자열내에서 시작, 끝 index 반환
- span() : 대상 문자열 내에서 시작, 끝 index를 tuple로 반환
🌓 match(대상문자열 [, pos=0])
- 대상 문자열의 시작 부터 정규식과 일치하는 것이 있는지 조회
- pos : 시작 index 지정
- 반환값
- Match 객체: 일치하는 문자열이 있는 경우
- None: 일치하는 문자열이 없는 경우
import re
# txt = "안녕하세요. 저 나이는 20세 입니다."
txt = "반갑습니다. 안녕하세요. 저 나이는 20세 입니다."
pattern = r'안녕' #literal 로만 만든 패턴
# 함수
m = re.match(pattern, txt) #패턴, 찾을 대상 -> 문장의 시작이 pattern과 일치하는지.
print(m)
if m:
print('찾은 문자열:', m.group())
print('찾은 문자열의 시작/끝 위치, 전체위치:', m.start(),m.end(),m.span())
else: #m == None
print('없음')
>>>
None
없음
🌓 search(대상문자열 [, pos=0])
- 대상문자열 전체 안에서 정규식과 일치하는 것이 있는지 조회
- pos: 찾기 시작하는 index 지정
- 반환값
- Match 객체: 일치하는 문자열이 있는 경우
- None: 일치하는 문자열이 없는 경우
txt = "반갑습니다. 안녕하세요. 저 나이는 20세 입니다.안녕하세요."
pattern = r'안녕하세요'
p = re.compile(pattern)
m = p.search(txt,pos=9) # 뒤에 안녕하세요가 있어도 앞에 있으면 그것만 검색한다. / but pos=9 로 하면 '9'이후의 값부터 검색함.
if m:
print(m.group(), m.span())
else:
print('없음')
>>>
안녕하세요 (28, 33)
🌓 findall(대상문자열)
- 대상문자열에서 정규식과 매칭되는 문자열들을 리스트로 반환
- 반환값
- 리스트(List) : 일치하는 문자열들을 가진 리스트를 반환
- 일치하는 문자열이 없는 경우 빈 리스트 반환
txt = '가격은 각각 4000, 5000, 15000, 25000, 10, 9, 236입니다.'
# pattern = r'\\d' # 숫자 1개
pattern = r'\\d+' # 숫자 1개 이상이의 숫자들
pattern = r'[가-힣]+' # 1개 이상의 한글들
p = re.compile(pattern)
m = p.findall(txt)
print(m)
>>>
['가격은', '각각', '입니다']
🌓 finditer(대상문자열)
- 패턴에 일치하는 모든 문자열을 찾아주는 Iterator => for문, list()
- 찾은 문자열을 Match 객체로 반환.
result = p.finditer(info)
print(type(result))
for m in result:
print(m)
📍 문자열 변경
- sub( ): 변경된 문자열 반환
- subn( ): 변경된 문자열, 변경개수 반환
🌓 sub(바꿀문자열, 대상문자열 [, count=양수])
- 대상문자열에서 패턴과 일치하는 것을 바꿀문자열로 변경한다.
- count: 변경할 개수를 지정. 기본: 매칭되는 문자열은 다 변경
- 반환값: 변경된 문자열
txt = 'test1, test2, test3, test4, test5'
pattern = r'\\D' # or r'[^0-9]'
p = re.compile(pattern)
m = p.sub('', txt) # 지우기 => '': 빈문자열 (0글자)로 변경
print(m)
>>>
12345
🌓 subn(바꿀문자열, 대상문자열 [, count=양수])
- sub()와 동일한 역할.
- 반환값 : (변경된 문자열, 변경된문자열개수) 를 tuple로 반환
#subn 의 n은 문자열의 갯수
txt = '오늘은 수요일 입니다.'
txt = """오늘은 수요일 입니다.
내일은 목요일 입니다.
내일은 금요일 입니다
"""
# txt = '오늘은 수요일 입니다.'
# 공백들을 공백한개로 변경.
#pattern = r' +' #공백들
pattern = r'\\s+' #\\s : 공백, tab, 엔터
p = re.compile(pattern)
# result = p.sub(' ', txt)cn
result, cnt = p.subn(' ', txt)
print('변경개수:', cnt)
print(result)
>>>
변경개수: 9
오늘은 수요일 입니다. 내일은 목요일 입니다. 내일은 금요일 입니다
📍 나누기(토큰화)
🌓 split(대상문자열)
- pattern을 구분자로 문장을 나눈다.
- 반환: 나눈 문자열을 원소로 하는 리스트
'사과,복숭아,배,수박'.split(',')
>>>
['사과', '복숭아', '배', '수박']
-------------
# txt = '사과,복숭아,배|수박'
p = re.compile(r'[,|]') # 구분자 패턴
p.split(txt)
>>>
['사과', '복숭아', '배', '수박']
4. 그룹핑(Grouping)
- 패턴 내에서 하위패턴을 만드는 것.
- 전체 패턴에서 일부 패턴을 묶어준다.
- 구문: (패턴)
📍 그룹핑 예
🌓 전체 패턴 내에서 일부 패턴을 조회
tel = "TEL: 010-1111-2222"
pattern = r'(\\d{2,3})-(\\d{3,4})-(\\d{4})'
p = re.compile(pattern)
m = p.search(tel)
print(m)
if m:
print(m.group()) # 패턴과 일치하는 전체 문장을 반환.
print(m.group(1)) # 첫번쨰() 로 묶인 하위그룹 패턴을 반환.
print(m.group(2))
print(m.group(3))
>>>
<re.Match object; span=(5, 18), match='010-1111-2222'>
010-1111-2222
010
1111
2222
----------------
m.group().split('-')[2]
>>>
'2222'
🌓 패턴 내에서 하위그룹 참조
- 지정한 “번호” 번째 패턴으로 매칭된 문자열과 같은 문자열을 의미
txt = """
010-1111-2222
010-2222-2222
010-3333-4444
010-5555-5555
"""
# 패턴: 국번과 번호가 같은 전화번호
pattern = r'\\d{2,3}-(\\d{3,4})-\\1' #\\1: 1번 하위그룹으로 찾은 값과 같은 값을 가진 것.(패턴뿐 아니라 값도 같아야 한다.)
p = re.compile(pattern) #(\\1): \\1도 그룹으로 만들 수 있다. 그럼 m.group(2) = (\\1) 이다.
for m in p.finditer(txt):
print(m.group())
>>>
010-2222-2222
010-5555-5555
🌓 패턴내의 특정 부분만 변경
print(info)
# 주민번호중에 마지막 6개 숫자를 #으로 변경
pattern = r'(\\d{6}-[012349])\\d{6}' # 찾은 것 중 남길것(변경안할 것)을 그룹으로 묶는다.
p = re.compile(pattern)
result = p.sub("\\g<1>######",info) #\\g<1>: 1번 그룹의 값으로 변경
print(result)
>>>
김정수 kjs@gmail.com 801023-1010221
박영수 pys.abc@gmail.com 700121-1120212
이민영 lmy-abc@naver.com 820301-2020122
김순희 ksh@daum.net 781223-2012212
오주연 ojy@daum.net 900522-1023218
김정수 kjs@gmail.com 801023-1######
박영수 pys.abc@gmail.com 700121-1######
이민영 lmy-abc@naver.com 820301-2######
김순희 ksh@daum.net 781223-2######
오주연 ojy@daum.net 900522-1######
group으로 묶인 것 참조(조회)
- 패턴 안에서 참조
- \\번호 , r'(\\d{3}) \\1' => 중복되는 것을 패턴으로 표현할 때.
- match 조회
- match객체.group(번호)
- sub() 함수에서 대체 문자로 참조
- \\g<번호>
5. Greedy 와 Non-Greedy
📍 Greedy(탐욕스러운-최대일치) 의 의미
- 주어진 패턴에 만족하는 문자열을 최대한 넓게(길게) 잡아 찾는다.
- 매칭시 기본 방식
📍 Non-Greedy(최소일치)
- 주어진 패턴에 만족하는 문자열을 최초의 일치하는 위치까지 찾는다
- 개수를 나타내는 메타문자(수량자)에 **?**를 붙인다.
- ?, +?, {m,n}?
txt = '<div>파이썬 <b>정규표현식</b> </div>'
pattern = r'<.+?>'
p = re.compile(pattern)
m = p.findall(txt)
print(m)
>>>
['<div>', '<b>', '</b>', '</div>']
txt = '<div>파이썬 <b>정규표현식</b> </div>'
pattern = r'<.+?>'
p = re.compile(pattern)
m = p.findall(txt)
print(m)
>>>
['<div>', '<b>', '</b>', '</div>']
6. 전방/후방 탐색
- 패턴과 일치하는 문자열을 찾을 때는 사용하되 반환(소비) 되지 않도록 하는 패턴이 있을 때 사용.
📍 전방탐색
- 반환(소비)될 문자열들이 앞에 있는 경우.
- 긍정 전방탐색
- %%%(?=패턴) : %%%-반환될 패턴
- 부정 전방탐색
- %%%(?!패턴) : 부정은 =를 !로 바꾼다.
info = """
TV 300001원 30개
컴퓨터 2300001원 50개
모니터 42000001원 70개
"""
# 가격만 조회
# pattern = r'\\d+원'
# 가격만 조회 -> 조회결과에서 '원'은 뺸다.'
pattern = r'\\d+(?=원)'
p = re.compile(pattern)
m = p.findall(info)
print(m)
>>>
['300001', '2300001', '42000001']
📍 후방탐색
- 반환(소비)될 문자열이 뒤에 있는 경우.
- 긍정 후방탐색
- (?<=패턴)%%%
- 부정 후방탐색
- (?<!패턴)%%%
반응형
'[T.I.L] : Today I Learned > Python' 카테고리의 다른 글
[Python] 10강_Iterable 과 Decorator (0) | 2023.04.09 |
---|---|
[Python] 9-2강_입출력 (2) | 2023.04.09 |
[Python] 9-1강_Path (0) | 2023.04.09 |
[Python] 8강_예외처리 (0) | 2023.04.09 |
[Python] 7강_패키지 모듈 import (0) | 2023.04.05 |