Python

파이썬 정규식 01

eloyb 2024. 12. 21. 15:37
반응형

이번에 다룰 주제는 정규 표현식, 또는 정규식이라고도 하는 주제를 다루어 보도록 하겠습니다. 문서이든 웹페이지이던 글 을 보다보면 특정한 규칙을 가진 문자열의 패턴으로 이루어진 문장들이 있습니다. 예를 들어 휴대전화 번호라든지, 사업자 번호, 주민번호, 메일주소등이 그런 예인데, 이런 문자열의 규칙을 찾아내거나 변환하기 위해서 사용되는 것이 정규식입니 다. 정규식은 파이썬에서만 쓰이는 것이 아니라 자바스크립트라던지, PHP, ASP 웹용 언어등에서도 광범위하게 쓰이는 것으로 한번 배워두면 다른 곳에서도 적용할 수 있는 장점이 있습니다.

정규식을 배우기 전에 우선 정규식을 이용하지 않는 방법으로 휴대전화 번호를 체크하는 코드를 알아보도록 하겠습니다.

 

def isPhone(text): if len(text) != 13: return False for i in range(0, 3): if not text[i].isdecimal(): return False if text[3] != '-': return False for i in range(4, 8): if not text[i].isdecimal(): return False if text[8] != '-': return False for i in range(9, 13): if not text[i].isdecimal(): return False return True print('010-5555-1234 는 휴대전화 번호 입니다.') print(isPhone('010-5555-1234')) print('02-111-2222 는 휴대전화 번호입니다.')

print(isPhone('02-111-2222'))

 

편집기모드에서 위의 코드를 입력 후에 저장을 한 후 F5키를 누릅니다.

1.  def isPhone(text)로 함수를 선언하고, 문자열의 길이가 13인지를 체크합니다.(len(text) != 13)

2.  for 반복문과 if 문을 이용해서 문자열이 111-2222-3333 구조로 이루어졌는지 첫번째 3개의 문자가 숫자로 이루 어졌는지(isdecimal())등을 체크합니다.

3.  모든 체크를 마치면 휴대전화 번호의 형식이 맞다면 print 문을 통해서 True 반환하고 휴대전화 형식이 아니라면 False를 반환하게 됩니다.

010-5555-1234 는 휴대전화 번호 입니다. True 02-111-2222 는 휴대전화 번호입니다. False >>> 이번에는 하나의 휴대전화번호만 있는 것이 아니라 여러개의 전화번호를 찾는 코드를 알아보도록 하겠습니다.

def isPhone(text): if len(text) != 13: return False for i in range(0, 3): if not text[i].isdecimal(): return False if text[3] != '-': return False for i in range(4, 8): if not text[i].isdecimal(): return False if text[8] != '-': return False for i in range(9, 13): if not text[i].isdecimal(): return False return True message = '고객님 제 전화번호가

010-1111-2222 에서 010-2222-3333 으로 바뀌었습니다. ' for i in range(len(message)): check = message[i:i+13] if isPhone(check): print('발견된 전화번호들은 ' + check)

편집기 모드에서 위의 코드를 입력 후에 저장을 한 후 F5키를 누릅니다.

첫번째 코드 예제와 똑같은 부분을 제외하고 다른 부분만 설명드리자면 check = message[i:i+13] check = message[0:13] 되므로 check 들어가는 값은 '고객님 전화번호가 0' 반환하고 for 반복문을 돌면서 값이 하 나씩 증가하게 되므로 두번째는 '객님 제 전화번호가 01'을 반환하게 되고, 계속 반환문을 돌다가 '010-1111-2222' 를 만나게 되면 return True 되고 print 문을 통해서 휴대전화번호를 출력해 줍니다. 이후에도 반복문은 계속 진행이 되고

 

(len(message) 통해서) 다른 휴대전화번호의 패턴을 발견하게 되면 휴대전화번호도 print 문을 통해서 출력을 해 주게 됩니다. 실행을 하면 아래와 같은 출력문을 확인할 수 있습니다.

발견된 전화번호들은 010-1111-2222 발견된 전화번호들은 010-2222-3333 >>> 정규식으로 표현하기

 

위의 코드를 이용해서도 휴대전화번호를 찾을 수는 있지만, 정규식을 이용하면 훨씬 간단히 휴대전화번호를 찾을 있 습니다. 정규식은 단순히 휴대전화번호뿐만 아니라, 패턴이 있는 문자열이라면 다른 형식의 데이터(메일주소, 사업자번호 등)도 쉽게 검증할 수 있는 장점이 있습니다. 예를 들어 위의 휴대전화번호같은 경우 정규식을 이용한다면 \d\d\d-

\d\d\d\d-\d\d\d\d 사용하여 한줄의 코드만으로 휴대전화 패턴을 찾아낼 있습니다. 여기에서 \d 정 규식에서는 임의의 숫자를 나타냅니다.

그러면 정규식에서 사용하는 문자클래스를 알아보도록 하겠습니다. 정규식에서 사용되는 문자 클래스의 의미는 아래와 같습니다.

문자 클래스          의미

 

\d                       숫자와 매칭

 

\D                      숫자가 아닌 것에 매칭

 

\w                      모든 문자, 모든 숫자, 언더스코어에 매칭

모든 문자, 모든 숫자, 언더스코어가 아닌 것과

\W

\s                       스페이스, , Enter 매칭

 

\S                       스페이스, , Enter 가 아닌 것과 매칭

 

정규식 객체의 search() 메서드는 전달된 문자열을 정규식에 일치하는 검사합니다. 정규식 패턴이 문자열에서 발견되 지 않으면 search() 메서드는 None 반환합니다. 패턴이 발견되면 search() 메서드는 Match 객체를 반환합니다. 검색 된 문자열에서 실제 일치하는 문자열을 반환하려면 group() 메서드를 사용합니다. 파이썬의 모든 정규식 함수는 re 모듈 에 있습니다. 그렇기 때문에 정규식을 사용하려면 re 모듈을 먼저 import 해주어야 합니다.

그러면 예를 들어보도록 하겠습니다.

>>> import re >>> phoneNumber = re.compile(r'\d\d\d-\d\d\d\d-\d\d\d\d') >>> i = phoneNumber.search('내 전화번호는 010-1111-2222 입니다.') >>> print(i.group()) 010-1111-2222 >>> 정규식을 사용하여 전화번호를 출력한 결과입니다. 어떻습니까? 처음의 코드에 비해서 정규식을 이용하면 훨씬 간결하 게 휴대전화번호를 검색해서 출력해 줍니다.

정규식을 이용하면 group() 메서드를 이용해서 전화번호를 지역번호와 전화번호로 구분해서 출력을 할 수가 있습니다. 예를 들어 (041)-(111-2222) 같은 전화번호가 있을 경우 group() 메서드를 이용하면 041 111-2222 따로 출력할

수가 있습니다.

>>> phoneNumber = re.compile(r'(\d\d\d)-(\d\d\d-\d\d\d\d)') >>> i = phoneNumber.search('내 전화번호는 041-111-2222 입니다.') >>> i.group(1) '041' >>> i.group(2) '111-2222' >>> i.group(0)

'041-111-2222' >>>

파이프(|)를 사용하여 여러 그룹중 일치하는 문자열 찾기

 

파이프(|) 이용하면 여러 표현식 하나와 일치하는 곳이면 어디에서나 사용할 있습니다. 아래의 예처럼 성유리 혹 은 이시영이 모든 검색 문자열에서 발견되면 일치하는 텍스트의 첫번째 일치 항목이 Match 객체로 반환됩니다.

>>> import re >>> names = re.compile(r'성유리|이시영') >>> i = names.search('성유리 혹은 이시영') >>> i.group() '성유리' >>> i = names.search('이시영 혹은 성유리') >>> i.group() '이시영' >>>

물음표(?)를 사용하여 선택적 문자열 사용하기

 

경우에 따라서는 해당 텍스트에서 선택적으로 일치시킬 패턴을 사용할 수가 있습니다. 물음표(?) 이용하면 옵션과 같이 선택적으로 일치시키는 정규식을 사용할 수 있습니다.

>>> import re >>> char = re.compile(r'Super(wo)?man') >>> i = char.search('Batman v Superman') >>> i.group() 'Superman' >>> j = char.search('Superwoman\'s adventure') >>> j.group() 'Superwoman' >>> 별표(*)를 사용하여 0개 이상의 문자 일치시키기

 

별표(*)를 사용하여 0개를 선택하거나 그 이상의 텍스트를 여러번 사용하여 정규식을 사용할 수 있습니다.

>>> import re >>> char = re.compile(r'Super(wo)*man') >>> i = char.search('Superman vs Batman') >>> i.group() 'Superman' >>> j = char.search('Find Superwowowoman') >>> j.group() 'Superwowowoman' >>> 플러스(+)를 사용하여 1개 이상의 문자 일치시키기

 

별표(*) 사용하면 0 이상을 선택하는 경우이지만 플러스(+) 사용하면 하나 이상의 일치를 의미합니다. 플러스(+) 는 적어도 한개 이상은 선택해야 한다는 점이 별표(*)와 다른 점입니다.

>>> char = re.compile(r'Super(wo)+man') >>> i = char.search('Find Superman') >>> i.group() Traceback (most recent call last): File "<pyshell#34>", line 1, in <module> i.group() AttributeError: 'NoneType' object has no attribute 'group' >>> i = char.search('Find Superwoman') >>> i.group() 'Superwoman' >>>

위처럼 플러스(+) 기호를 사용하면 괄호안의 문자는 반드시 한번은 선택해야 하므로, 한번도 포함을 하지 않고 출력을 하 면 에러 메시지가 나오게 됩니다.

 

중괄호{} 문자열 반복 일치시키기

 

중괄호{} 사용하여 반복하려는 특정 문자를 지정할 있습니다. 예를 들어 (Abc){3} AbcAbcAbc 일치합니다. (Abc){2,4} AbcAbc, AbcAbcAbc, AbcAbcAbcAbc와 일치합니다. (Abc){3,} Abc 3개 이상을 의미하고,

 

(Abc){,4} 0-4개의 Abc일치합니다.

>>> import re >>> char = re.compile(r'(Abc){3}') >>> i = char.search('AbcAbcAbc') >>> i.group() 'AbcAbcAbc'

>>> i = char.search('AbcAbc') >>> i.group() Traceback (most recent call last): File "<pyshell#42>", line 1, in

<module> i.group() AttributeError: 'NoneType' object has no attribute 'group' >>>

위에서 {3} 을 사용했는데 ('AbcAbc') 를 찾으려고 하면 일치하는 자료가 없기 때문에 에러메시지가 발생하게 됩니다.

 

 

댓글수3