List
- 정규 표현식
- 정규 표현식 I
- 정규 표현식 II
※ 정규 표현식은 줄여서 간단히 "정규식"이라고도 말한다.
.
^
*
+
?
{
}
[
]
\
(
)
문자클래스 [ ]
: "[ ]
사이의 문자들과 매치"`
[ ]
사이에는 어떤 문자도 들어갈 수 있다. 문자 클래스 [ ]
사용법
[abc]
= "a, b, c중 한 개의 문자와 매치"문자열 "a", "before", "dude"가 정규식 [abc]와 어떻게 매치되는가 ?
- "a"는 매치 # 정규식과 일치하는 문자 "a"가 있기 때문
- "before"은 매치 # 정규식과 일치하는 문자 "b"가 있기 떄문
- "dude" 는 매치불가 # 정규식과 일치하는 문자인 a,b,c중 아무것도 없기 떄문
[문자1-문자2]
: [문자1(from)-문자2(to)]
안 두문자 사이의 문자들과 매치"` - `[a-c]` = `[abc]`
- `[0-5]` = `[012345]`
- `[a-zA-Z]` = `[알파벳 모두]`
- `[0-9]` = `[0,1,2,3,4,5,6,7,8,9]`
[문자 클래스 사용시 주의할 점]
^
: 문자 클래스 안에 매타 문자^
를 사용할 경우에는 반대(not)라는 의미를 갖는다.[^0-9] = [0,1,2,3,4,5,6,7,8,9] 숫자가 아닌 문자와만 매치
[자주 사용하는 문자 클래스]
\d
=[0-9]
- 숫자와 매치\D
=[^0-9]
- 숫자가 아닌 것과 매치\s
=[ \t\n\r\f\v]
- whitespace 문자와 매치, 맨 앞의 빈 칸은공백문자(space)
를 의미\S
=[^ \t\n\r\f\v]
- whitespace 문자가 아닌 것과 매치\w
=[a-zA-Z0-9_]
- 문자+숫자(alphanumeric와 매치\W
=[^a-zA-Z0-9_]
- 문자+숫자(alphanumeric)가 아닌 문자와 매치
Dot
(.
) : \n
(줄바꿈 문자)를 제외한 모든문자와 매치re.DOTALL 옵션을 주면
\n
과도 매치된다.
Dot
(.
) 사용법a.b
= "a + 모든문자 + b"
, a와 b사이 어떤 문자가 들어가도 전부 매치된다.- "aab" 는 매치 # 가운데 문자 "a"가 모든 문자를 의미하는 .과 일치
- "a0b" 는 매치 # 가운데 문자 "0"가 모든 문자를 의미하는 .과 일치
- "abc"는 매치불가 # "a"문자와 "b"문자 사이에 문자가 하나도 없다.
Dot
(.
) 사용법 2a[.]b
= "a + Dot(.)문자 + b"
, 문자 클래스 안에 .
이 있으므로 a와 b사이 무조건 .
만 올수 있다. - "a.b"은 매치
- "a0b"은 매치불가
※ 만약
문자 클래스([])
내에Dot
(.
) 메타 문자가 사용된다면 이것은 "모든 문자"라는 의미가 아닌 문자.
그대로를 의미한다.
*
: *
바로 앞에 있는 문자가 0부터 무한대로 반복되야 매치*
사용법ca*t
= *
앞에있는 문자 a가 무한대로 반복 될수 있다.(반복이 없어도 매치되는거당)- "ct"는 매치 # "a"가 0번 반복
- "cat"는 매치 # "a"가 0번 이상 반복(1회 반복)
- "caaat"는 매치 # "a"가 0번 이상 반복(3회 반복)
+
: +
바로 앞에 있는 문자가 최소 1번 이상 반복되야 매치+
사용법 ca*t
= +
앞에있는 문자 a가 최소 1번 이상 될 수 있다.(0개 반복은 매치불가)- "ct"는 매치불가 # "a"가 0번 반복
- "cat"는 매치 # "a"가 1번 이상 반복(1회 반복)
- "caaat"는 매치 # "a"가 1번 이상 반복(3회 반복)
즉
*
는 반복 횟수 0부터 /+
는 반복 횟수 1부터 인 것이다.
반복 ({m,n}, ?)
: 반복 횟수를 고정하 수 있다.
{1,3}
: 1 ~ 3 반복{3,}
: 반복 횟수 3 이상{,3}
: 반복 횟수 3 이하즉
{1,}
=+
,{0,}
=*
반복 ({m,n}, ?)
사용법
{m}
= 반드시 m
번 반복
ca{2}t
= "c + a(반드시 2번 반복) + t"
-"cat" 는 매치불가 # "a"가 1번 반복
-"caat" 는 매치 # "a"가 2번 반복
{m, n}
= m
~n
반복
ca{2,5}t
= "c + a(2~5회 반복) + t"
-"cat" 는 일치 불가 # "a"가 1번만 반복
-"caat" 는 일치 # "a"가 2번 반복
-"caaaaat"는 일치 # "a"가 5번 반복
?
= {0, 1}
ab?c
= "a + b(있어도 되고 없어도 된다) + c"
- "abc"는 매치 # "b"가 1번 사용
- "ac"는 매치 # "b"가 0번 사용
** 이 자체가 패턴이당
>>> import re
>>> p = re.compile('ab*') # ab*를 컴파일 하고, 객체 p를 사용하여 이후 작업을 수행할 것이다
- 정규식을 컴파일할 때 특정 옵션을 주는 것도 가능
** 이 자체가 패턴이다.
>>> import re
>>> p = re.compile('[a-z]+')
match객체
를 돌려주고,>>> m = p.match("python") # "python"은 "[a-z]+정규식과 매치 된다.
>>> print(m)
<_sre.SRE_Match object at 0x01F3F9F8> # 그렇기 때문에 match 객체(m)를 돌려준다
None
을 돌려준다,>>> m = p.match("3 python") # 숫자 3 때문에 매치불가
>>> print(m)
None # None을 돌려준다
match()
사용법 p = re.compile(정규표현식) # 여기 안에 정규 표현식이 들어가야지~[a-z]+ 이런거 ~
m = p.match( 'string goes here' )
if m: # match의 결괏값이 있을 때만 그다음 작업을 수행하겠다는 것
print('Match found: ', m.group())
else:
print('No match')
>>> m = p.search("python")
>>> print(m)
<_sre.SRE_Match object at 0x01F3FA68> # match 와 동일
>>> m = p.search("3 python")
>>> print(m)
<_sre.SRE_Match object at 0x01F3FA30> # match와 다름/ search는 문자열 전체를 검색하기 때문에 "3 " 이후의 "python" 문자열과 매치
match 메서드
와search 메서드
는 문자열의 처음부터 검색할지의 여부에 따라 다르게 사용해야 한다.
>>> result = p.findall("life is too short") # 문자열의 'life', 'is', 'too', 'short' 단어를 각각 [a-z]+ 정규식과 매치
>>> print(result)
['life', 'is', 'too', 'short'] # 전부 매치되서 결괏값 출력
>>> 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 0x01F3FAD8>
<_sre.SRE_Match object at 0x01F3FAA0>
<_sre.SRE_Match object at 0x01F3F9F8>
- 즉
findall()
과finditer()
은 동일하다.- 결괏값을 출력하는 방법이 다를 뿐
findall()
->리스트
(list
)로 출력finditer()
->반복 가능한 객체
(iterator object
)로 출력
반복 가능한 객체
의 각 요소들은match 객체
이다.
match()
와 search()
객체의 매서드group()
: 매치된 문자열을 돌려준다.start()
: 매치된 문자열의 시작 위치를 돌려준다.end()
: 매치된 문자열의 끝 위치를 돌려준다.span()
: 매치된 문자열의 (시작, 끝)에 해당하는 튜플을 돌려준다.>>> m = p.match("python")
>>> m.group()
'python'
>>> m.start() # 슬라이싱 개념으로 생각하자.
0
>>> m.end() # 슬라이싱 개념으로 생각하자.
6
>>> m.span() # 슬라이싱 개념으로 생각하자.
(0, 6)
>>> m = p.search("3 python")
>>> m.group()
'python'
>>> m.start() # 딱 python만 가지고 오는거지, 슬라이싱개 개념으로 생각하자
2
>>> m.end() # 딱 python만 가지고 오는거지, 슬라이싱개 개념으로 생각하자
8
>>> m.span() # 딱 python만 가지고 오는거지, 슬라이싱개 개념으로 생각하자
(2, 8)
[모듈 단위로 수행]
re 모듈
축약 해보자 ㅡ ㅡ>> p = re.compile('[a-z]+') >> m = p.match("python")
>> m = re.match('[a-z]+', "python")
- 보통 한 번 만든 패턴 객체를 여러번 사용해야 할 때는 이 방법보다
re.compile
을 사용하는 것이 편하다.
re.DOTALL
= re.S
.
메타문자에 \n
는 제외되지만, \n
을 포함 시키고 싶다면 re.DOTALL
또는 re.S
옵션을 줘라>>> import re
>>> p = re.compile('a.b')
>>> m = p.match('a\nb') # 메타문자 . 을 사용했을 때 \n 은 매치 되지 않는다
>>> print(m)
None
re.DOTALL
옵션 사용>>> p = re.compile('a.b', re.DOTALL) # re.DOTALL 과 re.S 아무거나 사용하면 됌
>>> m = p.match('a\nb')
>>> print(m)
<_sre.SRE_Match object at 0x01FCF3D8>
re.IGNORECASE
= re.I
>>> p = re.compile('[a-z]', re.I) # [a-z]은 소문자만 의미 / re.I 옵션으로 대소문자 구별없이 매치
>>> p.match('python')
<_sre.SRE_Match object at 0x01FCFA30>
>>> p.match('Python')
<_sre.SRE_Match object at 0x01FCFA68>
>>> p.match('PYTHON')
<_sre.SRE_Match object at
0x01FCF9F8>
re.MULTILINE
= re.M
^
, $
와 연관이 있다.[
^
,$
의 사용]
^
는 문자열의 처음을 의미
^python ~
인 경우, 문자열의 처음은 항상 python으로 시작해야 매치된다.$
는 문자열의 마지막을 의미
~ python$
인 경우, 문자열의 마지막은 항상 python으로 끝나야 매치된다.
import re
p = re.compile("^python\s\w+") # "python"이라는 문자열로 시작, 그 뒤 "whitespace", 그 뒤 "단어"
data = """python one # data 는 여러 줄로 이루어져 있음
life is too short
python two
you need python
python three"""
print(p.findall(data))
['python one'] # 메타 문자 "^" 때문 python으로 시작하는 문자열인 첫번째 문자열만 출력
import re
p = re.compile("^python\s\w+", re.MULTILINE) # re.MULTILINE 옵션으로 인해 메타 문자 "^" 가 문자열 전체가 아닌 각 줄의 처음부터 보라고 하는것
data = """python one
life is too short
python two
you need python
python three"""
print(p.findall(data))
['python one', 'python two', 'python three']
re.VERBOSE
= re.X
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)
p = re.compile(r'\\section')
r'
활용
- 컴파일해야 하는 정규식이 Raw String임을 알려주는 파이썬 문법
- 위와 같이 진행 시
\section
을 찾도록 해준당
p = re.compile('\\\\section')
p = re.compile('\section')
\section
= [ \t\n\r\f\v]ection
\
를 한번 썻을 떄 앞의 \s
는 whitespace
로 해석되어 원하는 게 나오지 않는다.p = re.compile('\\section')
\\
사용하여 이스케이프 처리 시도 머리좀 씀\\
이 \
로 변경되어 \section
이 전달된다.p = re.compile('\section')
이럭게 된당