반응형
snowman95
코딩수련장
snowman95
전체 방문자
오늘
어제
  • 분류 전체보기 (230)
    • 앱테크 (3)
    • 옵시디언 (5)
    • 드라마, 영화 (1)
    • 개발자 이야기 (24)
    • 프로젝트 (10)
      • 프로젝트 방법론 (7)
      • 프로젝트 기록 (2)
      • Github (1)
    • 개발 지식 (0)
      • 디자인 패턴 (0)
    • 프론트엔드 개발 (5)
      • 테크트리 (2)
      • React.js (19)
      • ReactNative (2)
      • Next.js (6)
      • GraphQL (6)
      • 패키지 매니저 (2)
      • 라이브러리 (3)
      • 상태관리 라이브러리 (4)
      • Web 지식 (3)
      • HTML CSS (26)
      • Javascript (16)
      • 도구 (Tool) (3)
      • 성능 최적화 (1)
      • 디자인시스템 (0)
    • Python (53)
      • 모음집 (1)
      • 문법 (12)
      • 라이브러리 (15)
      • 알고리즘 (10)
      • 백준 문제풀이 (9)
      • 코딩테스트 (2)
      • 도구 (Tool) (3)
    • C++ (20)
      • 알고리즘 (6)
      • 삼성SW기출 (6)
      • 삼성 A형 (6)
    • 데이터사이언스 (1)
    • 인프라 (9)
      • 하드웨어 지식 (4)
      • Ansible (2)
      • Database (2)
      • 쉘스크립트 (1)
    • 주식 (0)
    • 취업 준비 (4)
      • 취업 이야기 (0)

블로그 메뉴

  • 홈
  • 태그

공지사항

인기 글

태그

  • 백준
  • 삼성SW역량테스트
  • A형
  • 전공 요약 #네트워크
  • 티스토리챌린지
  • 개발자이직
  • 25년도채용시장
  • 삼성SDS
  • 면접
  • 개발자취업시장
  • Next.js #graphql #tailwind.css
  • 오블완
  • 전공요약
  • 알고리즘
  • 나의 해방일지
  • 전공 요약 #데이터베이스
  • 기계식키보드 #nuphy
  • 언어
  • C++
  • 개발자이직회고

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
snowman95

코딩수련장

파이썬 (python) 라이브러리 - re (정규표현식)
Python/라이브러리

파이썬 (python) 라이브러리 - re (정규표현식)

2021. 3. 9. 22:08
728x90
반응형

m = p.match('a\nb') 

정규 표현식 설명
문자 클래스 [ ] [ ] 사이의 문자들과 매치
범위 [ - ] 하이픈(-) 추가하면 두 문자 사이 범위를 의미

[a-zA-Z] : 알파벳
[0-9] : 숫자
반대 ^ 맨앞에 ^를 붙이면 not의 의미

[^0-9] : 숫자가 아닌 것
자주 사용 대문자의 ^(반대)의 의미라고 기억

\d : 숫자와 매치, [0-9] 와 동일
\D : 숫자 아닌 것과 매치, [^0-9] 와 동일
\s : whitespace 문자와 매치, [ \t\n\r\f\v] 와 동일. 맨앞 빈칸은 공백문자를 의미함.
\S : whitespace 문자 아닌 것과 매치, [^ \t\n\r\f\v]와 동일.
\w : 문자+숫자와 매치, [a-zA-Z0-9] 와 동일
\W : 문자+숫자 아닌 것과 매치, [^a-zA-Z0-9] 와 동일
Dot . 줄바꿈 문자 \n 제외한 모든 문자와 매치
(문자 .을 쓰고싶다면 a[.]b)

a.b = a+모든문자+b
반복 * *앞에 있는 문자가 0회 이상 반복가능
(하나도 없어도 됨 : a가 하나도 없는 ct도 가능)

ca*t : ct, cat, caat, caaa…t
반복 + +앞에 있는 문자가 1회 이상 반복가능

ca+t : cat, caat, caaa…t
반복 {m,n}
반복 ?
반복 횟수를 제한하고 싶은 경우
m부터 n까지 매치가능, m또는 n 생략 가능

{m} : m회 이상, {,n} : n회 이하
? : {0,1} 을 의미한다. 즉, 문자 0~1개 (있거나 없거나)
\ \은 \\로 써줘야 문자로 인식함.  
\\은 \\\\로 써줘야 문자로 인식함. 

혹은
정규식 문자열 앞에 r 문자를 삽입해도 됨 (Raw String)
= 입력한 문자 그대로 인식

p = re.compile(r'\\section')

 

컴파일된 패턴 객체의 매서드

import re
p = re.compile('[a-z]+')   

한 객체를 여러 번 사용할때 쓴다.
Method 설명 예시
match() 문자열의 처음부터 정규식과 매치되는지 조사한다.

- 정규식과 매치될 때는 match 객체 반환
- 매치되지 않을 때는 None

re.compile()은 한 객체를 여러 번 사용할때 쓴다.
m = re.match(정규표현식, ‘string goes here’)
이렇게 하면 한번쓰고 끝남

p = re.compile(정규표현식) 
m = p.match(‘string goes here’) 
if m: print('Match found: ', m.group()) 
else: print('No match')

m = p.match(‘string’)
...
이런 식으로 재활용 가능
search() 문자열 전체를 검색하여 정규식과 매치되는지 조사한다.

- 정규식과 매치될 때는 match 객체를 돌려주고,
- 매치되지 않을 때는 None을 돌려준다.
p = re.compile(정규표현식)
m = p.search(“123123python") 

print(m) 
<_sre.SRE_Match object at 0x01F3FA68>
findall() 정규식과 매치되는 모든 문자열을 list로 반환 p = re.compile(정규표현식) 
result = p.findall("life is too short")
print(result)
[‘life’, ‘is’, ‘too’, ‘short’]
finditer() 정규식과 매치되는 모든 문자열을 iterator한 (반복가능한) match 객체들로 반환 p = re.compile(정규표현식) 
result = p.finditer("life is too short") 

print(result) 
<callable_iterator object at 0x01F5E390> 

for r in result:
   print(r)

<_sre.SRE_Match object at 0x01F3F9F8>
...
<_sre.SRE_Match object at 0x01F3F9F8>

 

math 객체의 메서드

Method 설명
group() 매치된 문자열을 돌려준다.
start() 매치된 문자열의 시작 위치를 돌려준다.
end() 매치된 문자열의 끝 위치를 돌려준다.
span() 매치된 문자열의 (시작, 끝)에 해당하는 튜플을 돌려준다.
m = p.match("python") 
m.group() 
# 'python' 
m.start()  # match 쓰면 항상 0, serach는 0아닐 수 있음
# 0 
m.end() 
# 6 
m.span() 
# (0, 6)

 

컴파일 옵션

p = re.compile('정규표현식', re.옵션) 
옵션을 사용할 때는 re.DOTALL처럼 전체 옵션 이름을 써도 되고 re.S처럼 약어를 써도 된다.
Method(약어) 내용 예시
DOTALL(S) Dot이 줄바꿈 문자('\n')를 포함하여 모든 문자와 매치할 수 있도록 한다. p = re.compile('a.b', re.DOTALL)
m = p.match('a\nb') 
print(m)
<_sre.SRE_Match object at 0x01FCF3D8>
IGNORECASE(I) 대소문자에 관계없이 매치할 수 있도록 한다. p = re.compile('[a-z]', re.I) 
p.match('python') 
<_sre.SRE_Match object at 0x01FCFA30> 
p.match('PYTHON') 
<_sre.SRE_Match object at 0x01FCF9F8>
MULTILINE(M) 여러줄과 매치할 수 있도록 한다. 

^는 문자열의 처음을 의미,
$는 문자열의 마지막을 의미

^python인 경우 문자열의 처음은 항상 python으로 시작해야 매치
^python$이라면 문자열의 마지막은 항상 python으로 끝나야 매치
p = re.compile("^python\s\w+", re.MULTILINE)
data = """python one 
life is too short 
python two 
python three""" 
print(p.findall(data))
['python one', 'python two', 'python three']
VERBOSE(X)  verbose 모드를 사용할 수 있도록 한다. 
(정규식을 보기 편하게 만들수 있고 주석등을 사용할 수 있게된다.)
charref = re.compile(r'&[#](0[0-7]+|[0-9]+|x[0-9a-fA-F]+);')
→ 아래와 같이 주석사용하여 표현가능
charref = re.compile(r""" 
&[#] # Start of a numeric entity reference 
( 0[0-7]+ # Octal form | [0-9]+ # Decimal form 
 | x[0-9a-fA-F]+ # Hexadecimal form 
) ; # Trailing semicolon 
""", re.VERBOSE)

 

메타문자

메타문자 설명 예시
| or과 동일한 의미로 사용
A|B 는 A 또는 B라는 의미
p = re.compile('Crow|Servo') 
m = p.match('CrowHello') 
print(m) 
<re.Match object; span=(0, 4), match='Crow'>
^ 문자열의 맨 처음과 일치함을 의미
컴파일 옵션 re.MULTILINE을 사용할 경우에는 
여러 줄의 문자열일 때 각 줄의 처음과 일치하게 된다.
문자로 쓰고싶으면 \^
print(re.search('^Life', 'Life is too short')) 
<re.Match object; span=(0, 4), match='Life'> 

print(re.search('^Life', 'My Life'))
None
$ $는 문자열의 끝과 매치함을 의미한다.
문자로 쓰고싶으면 \$
print(re.search('^Life', 'Life is too short'))
<re.Match object; span=(0, 4), match='Life'> 
print(re.search('^Life', 'My Life')) 
None
\A 문자열의 처음과 매치됨을 의미한다.  re.MULTILINE 옵션 사용할 경우 줄과 상관없이 전체 문자열의 처음하고만 매치된다.
\Z 문자열의 끝과 매치됨을 의미한다.  re.MULTILINE 옵션을 사용할 경우 전체 문자열의 끝과 매치된다.
\b 단어 구분자(Word boundary)이다. 보통 단어는 whitespace에 의해 구분된다.
→ no class at all의 class라는 단어와 매치됨을 확인할 수 있다.
p = re.compile(r'\bclass\b') 
print(p.search('no class at all')) 
<re.Match object; span=(3, 8), match='class'>
\B whitespace로 구분된 단어가 아닌 경우에만 매치된다. p = re.compile(r'\Bclass\B') 
print(p.search('no class at all')) 
None

 

 

그루핑 ()

group(인덱스) 설명
group(0) 매치된 전체 문자열
group(n) n 번째 그룹에 해당되는 문자열
구현하고자 하는 것 코드
ABC 문자열이 계속해서 반복되는지 조사하는 정규식 p = re.compile('(ABC)+') 
m = p.search('ABCABCABC OK?') 
print(m) 
# <re.Match object; span=(0, 9), match='ABCABCABC'>

print(m.group()) 
# ABCABCABC
이름 + " " + 전화번호 형태의 문자열을 찾는 정규식에서
전화번호만 뽑아내고 싶은 경우
p = re.compile(r"(\w+)\s+(\d+[-]\d+[-]\d+)") 
m = p.search("park 010-1234-1234") 
print(m.group(2)) 010-1234-1234
이름 + " " + 전화번호 형태의 문자열을 찾는 정규식에서
국번(010)만 뽑아내고 싶은 경우
p = re.compile(r"(\w+)\s+((\d+)[-]\d+[-]\d+)") 
m = p.search("park 010-1234-1234")
print(m.group(3)) 010
그루핑 설명 코드
그루핑 문자 재참조 (\b\w+)\s+\1은 (그룹) + " " + 앞에나온그룹 을 의미한다.
\1은 정규식의 그룹 중 첫 번째 그룹을 가리킨다
p = re.compile(r'(\b\w+)\s+\1') 
p.search('Paris in the the spring').group() 
'the the'
그루핑된 문자열에 이름 붙이기 그룹을 인덱스가 아닌 이름(Named Groups)으로 참조
(\w+) → (?P<name>\w+)
(?P<name>\w+)\s+((\d+)[-]\d+[-]\d+)
print(m.group("name"))
park
그루핑된 문자열에 이름 붙이고 재참조하기 그룹 이름을 사용하면 정규식 안에서 재참조 가능
(?P=그룹이름)
p = re.compile(r'(?P<word>\b\w+)\s+(?P=word)')
p.search('Paris in the the spring').group() 'the the'

 

 

전방 탐색 (Lookahead Assertions)

구분 설명 예시
긍정형 전방 탐색((?=...))  ... 에 해당되는 정규식과 매치되어야 하며 조건이 통과되어도 문자열이 소비되지 않는다. p = re.compile(".+(?=:)") 
m = p.search("http://google.com")
print(m.group())
http
검색 결과에서는 :이 제거된 후 돌려줌
부정형 전방 탐색((?!...)) ...에 해당되는 정규식과 매치되지 않아야 하며 조건이 통과되어도 문자열이 소비되지 않는다. *[.].*$ 는 파일이름+ . + 확장자이다.
만약 bat 확장자는 제외해야 한다면?
.*[.](?!bat$).*$

exe 역시 제외하라는 조건이 추가된다면?
.*[.](?!bat$|exe$).*$

 

Greedy vs Non-Greedy

구분 설명 예시
Greedy <.*>정규식의 매치 결과로 <html> 문자열을 돌려주기를 기대했을 것이다. 
하지만 * 메타 문자는 매우 탐욕스러워서 매치할 수 있는 최대한의 문자열
<html><head><title>Title</title> 문자열을 모두 소비한다.
s = '<html><head><title>Title</title>'  
print(re.match('<.*>', s).span()) 
# (0, 32) 
print(re.match('<.*>', s).group()) 
# <html><head><title>Title</title>
Non-Greedy non-greedy 문자인 ?를 사용하면 *의 탐욕을 제한할 수 있다.
non-greedy 문자인 ?는 *?, +?, ??, {m,n}?와 같이 사용할 수 있다. 
가능한 한 가장 최소한의 반복을 수행하도록 도와주는 역할을 한다.
print(re.match('<.*?>', s).group()) 
# <html>

 

문자열 변경

Method 설명 예시
sub() 첫 번째 매개변수는 "바꿀 문자열(replacement)"이 되고, 
두 번째 매개변수는 "대상 문자열"이 된다. 
같이 세 번째 매개변수로 count 값을 넘기면 count 횟수만큼 변경
→ 1 넣으면 딱 한 번만 바꾸기
blue | white | red라는 문자열이 colour로 변경
p = re.compile('(blue|white|red)')
p.sub('colour', 'blue socks and red shoes') '
colour socks and colour shoes'
처음 일치하는 blue만 colour라는 문자열로 한 번만 바꾸기
p.sub('colour', 'blue socks and red shoes', count=1)'
colour socks and red shoes'
sub() 사용 시 
참조 구문 사용하기
이름 + 전화번호의 문자열을 전화번호 + 이름으로 바꾸는 예이다. 
sub의 바꿀 문자열 부분에 \g<그룹이름>을 사용하면 
정규식의 그룹 이름을 참조
p = re.compile(r"(?P<name>\w+)\s+(?P<phone>(\d+)[-]\d+[-]\d+)") 
print(p.sub("\g<phone> \g<name>", "park 010-1234-1234")) 
010-1234-1234 park
p = re.compile(r"(?P<name>\w+)\s+(?P<phone>(\d+)[-]\d+[-]\d+)") 
print(p.sub("\g<2> \g<1>", "park 010-1234-1234")) 010-1234-1234 park
sub() 사용 시 
매개변수로 함수 넣기
hexrepl 함수는 match 객체(위에서 숫자에 매치되는)를 입력으로 받아 16진수로 변환하여 돌려주는 함수이다. 
sub의 첫 번째 매개변수로 함수를 사용할 경우 해당 함수의 첫 번째 매개변수에는 정규식과 매치된 match 객체가 입력된다. 
그리고 매치되는 문자열은 함수의 반환 값으로 바뀌게 된다
ef hexrepl(match): 
... value = int(match.group()) 
... return hex(value) 
... 
p = re.compile(r'\d+') 
p.sub(hexrepl, 'Call 65490 for printing, 49152 for user code.') 
'Call 0xffd2 for printing, 0xc000 for user code.'
subn() sub와 동일한 기능을 하지만 반환 결과를 튜플로 돌려줌.
반환된 첫 번째 요소는 변경된 문자열이고, 
두 번째 요소는 바꾸기가 발생한 횟수이다.
p = re.compile('(blue|white|red)') 
p.subn( 'color', 'blue socks and red shoes') 
('color socks and color shoes', 2)

 

반응형
저작자표시 동일조건 (새창열림)

'Python > 라이브러리' 카테고리의 다른 글

파이썬 (python) 라이브러리 - Pandas 판다스  (0) 2021.03.22
파이썬 (python) 라이브러리 - finpie  (1) 2021.03.19
파이썬 (python) 라이브러리 - yahoo_fin  (0) 2021.03.18
파이썬(python) 라이브러리 - numpy  (0) 2021.03.17
파이썬 (python) 라이브러리 - openpyxl, xlrd (excel 다루기)  (0) 2021.03.09
    'Python/라이브러리' 카테고리의 다른 글
    • 파이썬 (python) 라이브러리 - finpie
    • 파이썬 (python) 라이브러리 - yahoo_fin
    • 파이썬(python) 라이브러리 - numpy
    • 파이썬 (python) 라이브러리 - openpyxl, xlrd (excel 다루기)
    snowman95
    snowman95
    (17~19) Unity/Unreal Engine 게임 프로그래머 (20~21) System Administrator ___________ (22~) React 웹 프론트앤드 개발자 __________ 깃헙 : https://github.com/snowman95

    티스토리툴바