<6-1주차 수강 클립>
01. Python Programming 기초
34. 정규표현식 - 02. 정규표현식과 re모듈의 사용 - 2
35. 정규표현식 - 03. 정규표현식과 re모듈의 사용 - 3
36. 정규표현식 - 04. 정규표현식 연습문제 풀이
이번 주차는 저번 주에 이어 정규표현식과 re모듈의 사용법에 대해 알아보는 시간을 가졌습니다.
또한 드디어 파이썬 프로그래밍 기초를 마무리짓는 주차였네요!
>>수강 인증샷<<
34-35. 정규표현식 - 02. 정규표현식과 re모듈의 사용
- \ (back slash)
1. 다른 문자와 함께 사용될 때 특수한 의미
- \d : 숫자를 의미, [0-9]와 동일
- \D : 숫자가 아닌 문자 [^0-9]와 동일
- \s : 공백 문자(띄어쓰기, 탭, 엔터 등)
- \S : 공백이 아닌 문자
- \w : 알파벳대소문자, 숫자 [0-9a-zA-Z]와 동일
- \W : non alpha-numeric 문자 [^0-9a-zA-Z]와 동일
2. 메타 캐릭터가 캐릭터 자체를 표현하도록 할 경우 사용
- \. ('.' 캐릭터 그 자체) , \\ ('\' 캐릭터 그 자체)
import re
re.search(r'\sand', 'apple and banana')
: 결과: <re.Match object; span=(5, 9), match=' and'>
- .
- 모든 문자를 의미
re.search(r'.and', 'pand') #.: 특수한 의미_모든 문자를 의미
re.search(r'\.and', 'pand') #\.: '.'이 자체 의미 (검출x)
re.search(r'\.and', '.and') # (검출o)
re.search(r'p.g', 'pig')
- 반복패턴
- 패턴 뒤에 위치하는 *, +, ?는 해당 패턴이 반복적으로 존재하는지 검사
- '+' -> 1번 이상의 패턴이 발생
- '*' -> 0번 이상의 패턴이 발생 -> '없거나'도 표현
- '?' -> 0 혹은 1번의 패턴이 발생
- 반복을 패턴의 경우 greedy하게 검색 함, 즉 가능한 많은 부분이 매칭되도록 함
- e.g) a[bcd]*b 패턴을 abcbdccb에서 검색하는 경우
- ab, abcb, abcbdccb 전부 가능
- 하지만 최대한 많은 부분이 매칭된 abcbdccb가 검색된 패턴
- e.g) a[bcd]*b 패턴을 abcbdccb에서 검색하는 경우
#a[bcd]*b: a + b or c or d가 0번 이상 반복 + b
#패턴에 걸리는 경우: ab / abcb / abcbdccb
#결과: abcbdccb
#반복패턴의 경우 검색이 greedy함 (가능한 많은 부분이 매칭되도록 동작함)
re.search(r'a[bcd]*b', 'abcbdccb')
#b\w+a: b + 모든 문자 중 아무거나 하나가 1번 이상 반복 + b
#패턴에 걸리는 경우: bana / banana
#결과: banana (greedy search)
re.search(r'b\w+a', 'banana')
#패턴에 걸리는 경우: i / ii / (여기까지 검색 안함)iii
#결과: ii
#greedy함(i 보다는 ii)과 동시에
#가장 먼저 search(이미 i, ii 패턴 찾은 후에 g 나오므로 더 보지 않음)되는 게 있으므로
#ii 찾고 종료해버림
#0번째 인덱스부터 패턴 서칭
re.search(r'i+', 'piigiii')
re.search(r'pi+g', 'pg') #검출 x
re.search(r'pi*g', 'pg') #검출 o
: +와 *의 차이
- ^*, *$
- ^ 문자열의 맨 앞부터 일치하는 경우 검색
- $ 문자열의 맨 뒤부터 일치하는 경우 검색
#^가 들어가는 경우: 문자열의 '맨 앞'부터 일치하는 경우만 검출
#즉, 검출된 패턴 인덱스가 0부터 시작돼야 함
re.search(r'^b\w+a', 'cabana') #검출 x
#$가 들어가는 경우: 문자열의 '맨 뒤'부터 일치하는 경우만 검출
#즉, 검출된 패턴 인덱스가 제일 마지막 인덱스로 끝나야 함
re.search(r'b\w+a$', 'cabanap') #검출 x
- grouping
- ()을 사용하여 그루핑
- 매칭 결과를 각 그룹별로 분리 가능
- 패턴 명시 할 때, 각 그룹을 괄호() 안에 넣어 분리하여 사용
- 일단 패턴 먼저 만들고 나서 ()를 이용해 그루핑 하기!
- 그룹 별 번호 메기기
#예제: 이메일 패턴
m = re.search(r'\w+@.+', 'test@gmail.com')
m.group() #패턴 자체를 통째로 가져옴
: 결과: test@gmail.com
#골벵이 기준 id / domain 분리하고 싶을 경우 ()로 묶기
m = re.search(r'(\w+)@(.+)', 'test@gmail.com') #grouping
#그룹의 번호를 메길 수 있음
print(m.group(1))
print(m.group(2))
print(m.group(0)) #default: 전체 값 가져옴
: 결과:
test
gmail.com
test@gmail.com
- {}
- *, +, ?을 사용하여 반복적인 패턴을 찾는 것이 가능하나, 반복의 횟수 제한은 불가
- 패턴뒤에 위치하는 중괄호{}에 숫자를 명시하면 해당 숫자 만큼의 반복인 경우에만 매칭
- {4} - 4번 반복
- {3,4} - 3 ~ 4번 반복 띄어쓰기 하면 검출 안됨
re.search(r'pi{3,5}g', 'piiiiig') #3이상 5이하, 최대한 greedy하게 동작
: 결과: <re.Match object; span=(0, 7), match='piiiiig'>
- 미니멈 매칭(non-greedy way)
- 기본적으로 *, +, ?를 사용하면 greedy(맥시멈 매칭)하게 동작함
- *?, +?을 이용하여 해당 기능을 구현
#원하는 것: <html>
#결과: <html>haha</html>
#최대한 greedy하게 동작하기 때문
re.search(r'<.+>', '<html>haha</html>')
: greedy
#끝에 '?' 붙이면 minimum으로 찾음
re.search(r'<.+?>', '<html>haha</html>')
: non-greedy
- {}? (반복 횟수 설정_{})
- {m,n}의 경우 m번 에서 n번 반복하나 greedy하게 동작
- {m,n}?로 사용하면 non-greedy하게 동작. 즉, 최소 m번만 매칭하면 만족
#greedy(maximum)
re.search(r'a{3,5}', 'aaaaa')
#non-greedy(minimum)
re.search(r'a{3,5}?', 'aaaaa')
- match
- search와 유사하나, 주어진 문자열의 시작부터 비교하여 패턴이 있는지 확인
- 시작부터 해당 패턴이 존재하지 않다면 None 반환
re.match(r'\d\d\d', 'my number is 123') #검출 x (맨 처음부터 맞지 않음)
re.match(r'\d\d\d', '123 is my number') #검출 o
re.search(r'^\d\d\d', '123 is my number') #^ 써주면 search 함수로도 동일한 기능 가능
- findall
- search가 최초로 매칭되는 패턴만 반환한다면, findall은 매칭되는 전체의 패턴을 반환
- 매칭되는 모든 결과를 리스트 형태로 반환
re.findall(r'[\w-]+@[\w.]+', 'test@gmail.com haha test2@gmail.com nice test test')
: 결과: ['test@gmail.com', 'test2@gmail.com']
- sub
- 주어진 문자열에서 일치하는 모든 패턴을 replace
- 그 결과를 문자열로 다시 반환함
- 두번째 인자는 특정 문자열이 될 수도 있고, 함수가 될 수 도 있음
- count가 0인 경우는 전체를, 1이상이면 해당 숫자만큼 치환 됨
- count의 default값은 0
re.sub(r'[\w-]+@[\w.]+', 'great' , 'test@gmail.com haha test2@gmail.com nice test test')
: 결과: 'great haha great nice test test'
re.sub(r'[\w-]+@[\w.]+', 'great' , 'test@gmail.com haha test2@gmail.com nice test test', count = 1)
: 결과: 'great haha test2@gmail.com nice test test'
- compile
- 동일한 정규표현식을 매번 다시 쓰기 번거로움을 해결 (패턴 객체를 미리 만들어 재활용 가능하도록)
- compile로 해당표현식을 re.RegexObject 객체로 저장하여 사용가능
email_reg = re.compile(r'[\w-]+@[\w.]+') #정규표현식을 컴파일, 객체로 만들어버림
email_reg.search('test@gmail.com haha good') #문자열만 넘겨주면 됨!
36. 정규표현식 - 04. 정규표현식 연습문제 풀이
- 아래 뉴스에서 이메일 주소를 추출해 보세요
- 다음중 올바른 (http, https) 웹페이지만 찾으시오
import requests
from bs4 import BeautifulSoup
# 위의 두 모듈이 없는 경우에는 pip install requests bs4 실행
def get_news_content(url):
response = requests.get(url)
content = response.text
soup = BeautifulSoup(content, 'html5lib')
div = soup.find('div', attrs = {'id' : 'harmonyContainer'})
content = ''
for paragraph in div.find_all('p'):
content += paragraph.get_text()
return content
news1 = get_news_content('https://news.v.daum.net/v/20190617073049838')
print(news1)
webs = ['http://www.test.co.kr',
'https://www.test1.com',
'http://www.test.com',
'ftp://www.test.com',
'http:://www.test.com',
'htp://www.test.com',
'http://www.google.com',
'https://www.homepage.com.']
강의 링크: https://bit.ly/3cB3C8y
'코딩 > 머신러닝&데이터 분석 강의' 카테고리의 다른 글
[머신러닝 인강] 7-1주차: API의 활용 (0) | 2021.03.30 |
---|---|
[머신러닝 인강] 6-2주차: 웹 기본 지식 이해하기 (0) | 2021.03.28 |
[머신러닝 인강] 5-2주차: 클래스와 인스턴스, 정규표현식 (0) | 2021.03.21 |
[머신러닝 인강] 5-1주차: 클래스와 인스턴스 (0) | 2021.03.19 |
[머신러닝 인강] 4-2주차: 클래스와 인스턴스 (0) | 2021.03.14 |