반응형
Preface
오늘은 정규 표현식의 기초를 공부했다.
아직 코드를 짜는 것도 쉽지 않은데, 정규 표현식을 사용하여 복잡한 코드를 간단하게 바꾸는 방법을 공부하다 보니 생각보다 머리가 아프고 복잡했다.
정규 표현식도 라이브러리와 마찬가지로 매번 사용하는 것이 아니므로, 주요한 몇 가지의 사용 방법만을 익힌 후 나머지는 필요할 때마다 문서를 찾아 코드에 적용하는 것이 좋을 것 같다.
1. 정규 표현식 시작하기
- [ ] : 문자 클래스
- 문자 클래스로 만들어진 정규식은 "[ ] 사이의 문자들과 매치"라는 의미를 갖는다.
- 문자 클래스를 만드는 메타 문자인 [ ] 사이에는 어떤 문자도 들어갈 수 있다.
- [ ] 안의 두 문자 사이에 하이픈(-)을 사용하면 두 문자 사이의 범위(From - To)를 의미한다.
→ [a-zA-Z] : 알파벳 모두
→ [0-9] : 숫자
- 자주 사용되는 문자 클래스
- \d : 숫자와 매치, [0-9]와 동일한 표현식이다.
- \D : 숫자가 아닌 것과 매치, [^0-9]와 동일한 표현식이다.
- \s : whitespace 문자와 매치, [ \t\n\r\f\v]와 동일한 표현식이다. 맨 앞의 빈 칸은 공백문자(space)를 의미한다.
- \S : whitespace 문자가 아닌 것과 매치, [^ \t\n\r\f\v]와 동일한 표현식이다.
- \w : 문자+숫자(alphanumeric)와 매치, [a-zA-Z0-9_]와 동일한 표현식이다.
- \W : 문자+숫자(alphanumeric)가 아닌 문자와 매치, [^a-zA-Z0-9_]와 동일한 표현식이다.
- 정규 표현식의 Dot(.) 메타 문자는 줄바꿈 문자인 \n을 제외한 모든 문자와 매치됨을 의미한다.
→ ex) 'a.b' = 'a + 모든문자 + b'
→ ex) 'a[ . ]b = 'a + Dot(.)문자 + b'
- * : * 바로 앞에 있는 문자가 0부터 무한대로 반복될 수 있다는 의미이다.
- + : + 바로 앞에 있는 문자가 최소 1번 이상 반복될 때 사용한다
→ 즉 *가 반복 횟수 0부터라면 +는 반복 횟수 1부터인 것이다.
- {m, n} 정규식을 사용하면 반복 횟수가 m부터 n까지 매치할 수 있다.
→ 둘 중 하나 생략 가능
- ? 메타문자가 의미하는 것은 {0, 1} 이다.
→ 있어도 되고, 없어도 됨
2. 정규식을 이용한 문자열 검색
import re
p = re.compile('ab*')
# 정규 표현식을 컴파일하기 위한 과정
# 패턴이란 정규식을 컴파일한 결과이다.
import re
p = re.compile('[a-z]+')
m = p.match('python')
print(m)
n = p.match('3 python')
print(n)
# 문자열의 처음부터 정규식과 매치되는지 조사한다.
import re
p = re.compile('[a-z]+')
m = p.match('string goes here')
if m:
print('Match found: ', m.group())
else:
print('No match')
# match 의 결괏값이 있을 때만 그다음 작업을 수행하겠다는 의미
import re
p = re.compile('[a-z]+')
m = p.search('3 python')
print(m)
# match 는 문자열의 처음부터 검색하므로 None 을 출력하지만,
# search 는 문자열의 전체를 검색하므로 3 이후의 python 문자열과 매치된다.
import re
p = re.compile('[a-z]+')
result = p.findall('life is too short')
print(result)
# split 함수와 비슷한 기능?
# 정규식과 매치되는 모든 문자열(substring)을 리스트로 돌려준다.
result2 = p.finditer('life is too short')
print(result2)
for r in result2:
print(r)
# 정규식과 매치되는 모든 문자열(substring)을 반복 가능한 객체로 돌려준다.
import re
p = re.compile('[a-z]+')
m = p.match('python')
# 위 코드를 축약하여 m = re.match('[a-z]+', "python") 처럼 사용할 수도 있다.
print(m.group())
# 매치된 문자열을 돌려준다.
print(m.start())
# 매치된 문자열의 시작 위치를 돌려준다.
print(m.end())
# 매치된 문자열의 끝 위치를 돌려준다.
print(m.span())
# 매치된 문자열의 (시작, 끝)에 해당하는 튜플을 돌려준다.
3. Match 객체 메서드
import re
p = re.compile('a.b')
m = p.match('a\nb')
print(m, '\n')
p = re.compile('a.b', re.DOTALL)
m = p.match('a\nb')
print(m, '\n')
# DOTALL(S) - '.' 이 줄바꿈 문자를 포함하여 모든 문자와 매치할 수 있도록 한다.
# 옵션을 사용할 때는 re.DOTALL 처럼 전체 옵션 이름을 써도 되고 re.S 처럼 약어를 써도 된다.
p = re.compile('[a-z]+', re.IGNORECASE)
print(p.match('python'))
print(p.match('Python'))
print(p.match('PYTHON'), '\n')
# IGNORECASE(I) - 대소문자에 관계없이 매치할 수 있도록 한다.
p = re.compile('^python\s\w+')
data = """python one
life is too short
python two
you need python
python three"""
print(p.findall(data))
p = re.compile('^python\s\w+', re.MULTILINE)
data = """python one
life is too short
python two
you need python
python three"""
print(p.findall(data),'\n')
# MULTILINE(M) - 여러줄과 매치할 수 있도록 한다. (^, $ 메타문자의 사용과 관계가 있는 옵션이다)
# ^는 문자열의 처음을 의미하고, $는 문자열의 마지막을 의미한다.
char = 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)
# VERBOSE(X) - verbose 모드를 사용할 수 있도록 한다. (정규식을 보기 편하게 만들수 있고 주석등을 사용할 수 있게된다.)
# 따옴표 앞 r은 백슬래시를 특수문자로 출력시켜준다.
출처 : https://wikidocs.net/4308
728x90
반응형
댓글