파이썬

6주차, 정규식 실습

호놀롤루 2022. 1. 31. 20:00

 

Import re

p = re.compile('a.b') # 첫번째가 a고, 두번째는 \n, 줄바꿈을 제외한 모든 문자가 와도 되고 세번째가

                                    # b인 문자열 매치

re.match(p, 'a\tb') #  매치가 됨

p.match('a\tb') # 위에 거랑 같은 매치 됨

 

만약 성과 주민번호를 받고, 뒷자리를 *로 표기하고 싶다면

import re

 

data = """

park 800423-6123456

im 940305-5293848

"""

p = re.compile("(\d{6})[-]\d{7}")

print(p.sub("\g<1>-*******", data))

 

//

park 800423-*******

im 940305-*******

 

이 때 \g<1>는 ()쳐진 패턴의 첫번째를 의미한다.

패턴.sub("대체할 문자열", 원래 문자열) 즉, (\d{6})에 해당하는 나오는 숫자가 6개 연속으로

나오는 부분만 가져오고, 나머지는 -*******로 채운 것이다.

 

import re
p = re.compile('a.b') # \n을 제외한 문자
m = p.match('a\nb')
print(m)
m = p.match('akb')
print(m)
m = p.match('a.b')
print(m)
p = re.compile('a.b', re.DOTALL) # \n도 매치하독 함
m = p.match('a\nb')
print(m)
m = p.match('akb')
print(m)
 
//
None
<re.Match object; span=(0, 3), match='akb'>
<re.Match object; span=(0, 3), match='a.b'>
<re.Match object; span=(0, 3), match='a\nb'>
<re.Match object; span=(0, 3), match='akb'>
 
 

ㅇㅁㄴㅇ

p = re.compile('a[\w\W]b') 로 하면 줄바꿈까지매치 가능, 즉 모든 문자랑 매치 가능

p = re.compile('a[\s\S]b') 도 가능

 

import re
p = re.compile("a[.]{3,}") # 점(.)이 3자이상
# p = re.compile("a.{3,}") # \n을 제외하고 아무글자나 3자이상
print(p.match("acccb"))
print(p.match("a....b"))
print(p.match("aaab"))
print(p.match("a.cccb"))
 
None
<re.Match object; span=(0, 5), match='a....'>
None
None
import re
p = re.compile("[a-z]+") # 영문자 소문자 여러개
# 012345678
m = p.search("5 python")
print(m.start() + m.end()) # 2 + 8
# m.start() pattern에 맞는 첫번째 인덱스
# m.end() pattern에 맞는 마지막 인덱스
 
// 10

m.group()을 하면 매칭된 문자열('python')을 받을 수 있다.

 

import re
data = """
park 010-1234-5678
kim 010-1111-2222"""
# 이름 전화번호 1,2 전화번호 끝 4자리
p = re.compile('(\w+)\s(\d+[-]\d+)[-](\d+)') # \w는 숫자 또는 문자 여러개, \s는 화이트 스페이스
#, 빈칸 즉 이름 뒤 띄어쓰기,  그리고 하이픈-, \d는 숫자 여러개,  하이픈 한 번 더하고 숫자 여러개
# 일반 괄호를 쓰는 이유는 그룹화하기 위함이다.
 
print(p.sub("\g<2>-**** \g<1>", data)) // 위에서 지정한 첫번째 괄호가 \g<1> , 2번째 괄호가
# \g<2>다. 그렇게 나온 결과가 맞으면 data
print('========================')
for i in data.split("\n"): # 3건 공란,2건
    m = p.search(i)
    if m != None:
        print(m.group(2)+"-****"+" "+m.group(1)) # m.group(1)은 첫번째 괄호의 정규식에
# 해당하는 그룹에 매칭된 결과를 출력하고, 2는 두번째 패턴에 해당되는 것
 
//
010-1234-**** park
010-1111-**** kim
========================
010-1234-**** park
010-1111-**** kim

같은 걸 서로 다른 두 방법으로 코딩한 것이다. 

첫번째의 경우 g<2>는 (\d+[-]\d+) 숫자가 여러번 반복되고, - 하이픈이 나온 후 숫자가 여러번

반복되니 전화번호의 ???-???? 즉 앞자리 숫자에 해당한다.

 

그리고 g<1>의 (\w+)는 숫자나 문자가 반복되는 걸 말한다. 그러니 이름까지 문자열이 되고,

띄어쓰기, 화이트 스페이스에 의해 막아진다.