본문 바로가기

파이썬 Python

[Python] 중급 3강 정규 표현식 Regular expressions

[] (문자 클래스)

[] 사이에 있는 문자와 매치

[-] 사이에 있는 문자와 매치

 

. (Dot)

\n를 제외한 모든 문자와 매치

 

* 0번 이상 반복

+ 1번 이상 반복

 

?

0번 혹은 1번 매치됨

 

^

문자열의 시작을 의미

 

$

문자열의 끝을 의미

 

{n, m}

n~m번 반복

 

문자 클래스 설명
\d 숫자 [0-9]
\D 숫자가 아님 [^0-9]
\w 숫자와 문자 [a-zA-Z0-9]
\W 숫자나 문자가 아님 [^a-zA-Z0-9]
\s 공백 [\t\n\r\f\v]
\S 공백이 아님 [^\t\n\r\f\v]

 

 

 

정규 표현식 사용하기

import re

 

p = re.compile(정규표현식) Pattern

r = p.match(문자열) Match

 

Match

함수 설명
match 문자열 처음부터 정규식과 매치
search 문자열 전체에서 정규식과 매치
findall 정규식과 매치되는 모든 문자열을 리스트로 반환
finditer 정규식과 매치되는 모든 문자열을 반복 가능한 객체로 반환

 

import re

p = re.compile("[abo]")
print(type(p))

Out:

<class 're.Pattern'>

 

import re

p = re.compile("[abo]")

fruit = "Apple Banana Orange"
print("match fruit:", p.match(fruit))

Out:

match fruit: None

문자열 fruit이 문자 a, b 혹은 o로 시작되지 않기 때문에 None을 반환한다.

 

import re

p = re.compile("[abo]")

print("match fruit:", p.match("aba"))
print("match fruit:", p.match("banana"))

Out:

match fruit: <re.Match object; span=(0, 1), match='a'>
match fruit: <re.Match object; span=(0, 1), match='b'>

문자열 "aba"는 (0, 1) 구간에 문자 a가 있고 문자열 "banana"는 (0, 1) 구간에 문자 b가 있다.

 

import re

p = re.compile("[abo]")

r = p.match("aaa")
if r:
    print(r.group(), r.span())
else:
    print("no match")

Out:

a (0, 1)

group은 정규 표현식에서 소괄호를 사용하여 지정할 수 있다. 현재는 group을 따로 지정하지 않았기 때문에 매치되는 문자가 반환되었다. span은 매치되는 문자의 인덱스이다.

 

import re

p = re.compile("[abo]")
fruit = "Apple Banana Orange"

print("search:", p.search(fruit))
print("findall:", p.findall(fruit))
print("finditer:", p.finditer(fruit))
for i in p.finditer(fruit):
    print(i)

Out:

search: <re.Match object; span=(7, 8), match='a'>
findall: ['a', 'a', 'a', 'a']
finditer: <callable_iterator object at 0x033FFF10>
<re.Match object; span=(7, 8), match='a'>
<re.Match object; span=(9, 10), match='a'>
<re.Match object; span=(11, 12), match='a'>
<re.Match object; span=(15, 16), match='a'>

finditer가 iterator를 반환하므로 for문을 이용해서 출력한다.

 

import re

p = re.compile("[a-z]")
fruit = "Apple Banana Orange"
r = p.search(fruit)
if r is not None:
    print(r.group(), r.span())
print(p.findall(fruit))

Out:

p (1, 2)
['p', 'p', 'l', 'e', 'a', 'n', 'a', 'n', 'a', 'r', 'a', 'n', 'g', 'e']

문자열 fruit에서 소문자로 된 문자를 찾는 예제이다. search는 가장 먼저 찾은 문자열을 반환한다.

 

import re

p = re.compile("[A-Z]+[a-z]+")
fruit = "Apple Banana Orange"
r = p.search(fruit)
if r is not None:
    print(r.group(), r.span())
print(p.findall(fruit))

Out:

Apple (0, 5)
['Apple', 'Banana', 'Orange']

+를 사용해 1번 이상 반복하는 문자, 즉 문자열을 찾을 수 있다.

 

import re

p = re.compile("[a-zA-Z]+")
fruit = "Apple Banana Orange"
r = p.search(fruit)
if r is not None:
    print(r.group(), r.span())
print(p.findall(fruit))

Out:

Apple (0, 5)
['Apple', 'Banana', 'Orange']

위와 같은 출력이 나온다.

 

import re

p = re.compile(".+")
fruit = "Apple Banana Orange"
r = p.search(fruit)
if r is not None:
    print(r.group(), r.span())
print(p.findall(fruit))

Out:

Apple Banana Orange (0, 19)
['Apple Banana Orange']

.을 이용하면 모든 문자열과 매치된다.

 

import re

p = re.compile("\\w+")
fruit = "Apple Banana Orange"
r = p.search(fruit)
if r is not None:
    print(r.group(), r.span())
print(p.findall(fruit))

Out:

Apple (0, 5)
['Apple', 'Banana', 'Orange']

문자 클래스 \w가 Escape sequence로 인식되지 않도록 하기 위해 앞에 \를 한 번 더 쓴다. \w는 모든 숫자와 문자에 매치되므로 공백을 제외한 문자열이 반환된다.

 

import re

print("*와 + 비교 *", re.findall("[A-Z]*[a-z]+", "apple"))
print("*와 + 비교 +", re.findall("[A-Z]+[a-z]+", "apple"))
print("*와 + 비교 +", re.findall("[A-Z]?[a-z]+", "apple"))

Out:

*와 + 비교 * ['apple']
*와 + 비교 + []
*와 + 비교 + ['apple']

*는 0번 이상, 즉 0번만 나와도 매치되고 +는 1번 이상 나와야 매치된다. ?는 0번 혹은 1번만 나와야 매치된다.

 

import re

print("반댈세! ^", re.findall("[^a-zA-Z]", "apple"))
print("반댈세! ^", re.findall("[^a-zA-Z]", "apple5000"))
print("반댈세! ^", re.findall("[^a-zA-Z]+", "apple5000"))

Out:

반댈세! ^ []
반댈세! ^ ['5', '0', '0', '0']
반댈세! ^ ['5000']

 

import re

phone = "010-1234-5678"
p = re.compile("^[0-9]{3}-[0-9]{3,4}-[0-9]{4,}$")
r = p.search(phone)
if r is not None:
    print(r.group())
else:
    print("no match")

print(p.findall(phone))

Out:

010-1234-5678
['010-1234-5678']

 

 

 

Raw string

r"문자열"

문자열 안에 \를 쓰면 Escape sequence를 의미하게 되는데 문자열을 Raw string으로 선언하면 \를 문자 그대로 사용한다.

import re

phone = "010-1234-5678"
p = re.compile(r"^\d{3}-\d{3,4}-\d{4,}$")
r = p.search(phone)
if r is not None:
    print(r.group())
else:
    print("no match")

print(p.findall(phone))

Out:

010-1234-5678
['010-1234-5678']

 

import re

r = re.search(r"(\w+)\s?:\s?(\d+)", "Apple : 5000")
if r is not None:
    print(r.group(0), r.span(0))
    print(r.group(1), r.span(1))
    print(r.group(2), r.span(2))

Out:

Apple : 5000 (0, 12)
Apple (0, 5)
5000 (8, 12)

 

정규 표현식은 특정 문자열을 찾을때 코드 수를 줄여준다.

'파이썬 Python' 카테고리의 다른 글

[Python] 중급 2강 문자열 포매팅  (0) 2021.02.25
[Python] 중급 1 문자열  (0) 2021.02.25
[Python] 초급 12 클래스 예제  (0) 2021.02.21
초급 10, 11 클래스와 상속  (0) 2021.01.23
초급 9 XML  (0) 2021.01.15