점프 투 파이썬 00장 들어가기 전에 00-1 머리말 00-2 저자소개 00-3 주요변경이력 00-4 책 구입 안내 01장 파이썬이란 무엇인가? 01-1 파이썬이란? 01-2 파이썬의 특징 01-3 파이썬으로 무엇을 할 수 있을까? 01-4 파이썬 설치하기 01-5 파이썬 둘러보기 01-6 파이썬과 에디터 02장 파이썬 프로그래밍의 기초, 자료형 02-1 숫자형 02-2 문자열 자료형 02-3 리스트 자료형 02-4 튜플 자료형 02-5 딕셔너리 자료형 02-6 집합 자료형 02-7 불 자료형 02-8 자료형의 값을 저장하는 공간, 변수 02장 연습문제 03장 프로그램의 구조를 쌓는다! 제어문 03-1 if문 03-2 while문 03-3 for문 03장 연습문제 04장 파이썬의 입력과 출력 04-1 함수 04-2 사용자 입력과 출력 04-3 파일 읽고 쓰기 04-4 프로그램의 입력과 출력 04장 연습문제 05장 파이썬 날개달기 05-1 클래스 05-2 모듈 05-3 패키지 05-4 예외 처리 05-5 내장 함수 05-6 표준 라이브러리 05-7 외부 라이브러리 05장 연습문제 06장 파이썬 프로그래밍, 어떻게 시작해야 할까? 06-1 내가 프로그램을 만들 수 있을까? 06-2 3과 5의 배수 합하기 06-3 게시판 페이징하기 06-4 간단한 메모장 만들기 06-5 탭을 4개의 공백으로 바꾸기 06-6 하위 디렉터리 검색하기 06-7 파이보 06-8 코딩도장 07장 파이썬 고급주제 07-1 파이썬과 유니코드 07-2 클로저와 데코레이터 07-3 이터레이터와 제너레이터 07-4 파이썬 타입 어노테이션 08장 정규표현식 08-1 정규 표현식 살펴보기 08-2 정규 표현식 시작하기 08-3 강력한 정규 표현식의 세계로 09장 종합문제 10장 풀이 11장 마치며 Show 이번에는 문자열이 숫자로 되어있는지 판단해보겠습니다. 다음과 같이 [ ](대괄호) 안에 숫자 범위를 넣으며 * 또는 +를 붙입니다. 숫자 범위는 0-9처럼 표현하며 *는 문자(숫자)가 0개 이상 있는지, +는 1개 이상 있는지 판단합니다.
>>> re.match('[0-9]*', '1234') # 1234는 0부터 9까지 숫자가 0개 이상 있으므로 패턴에 매칭됨 <_sre.SRE_Match object; span=(0, 4), match='1234'> >>> re.match('[0-9]+', '1234') # 1234는 0부터 9까지 숫자가 1개 이상 있으므로 패턴에 매칭됨 <_sre.SRE_Match object; span=(0, 4), match='1234'> >>> re.match('[0-9]+', 'abcd') # abcd는 0부터 9까지 숫자가 1개 이상 없으므로 패턴에 매칭되지 않음 그럼 *와 +는 어디에 활용할까요? 다음과 같이 a*b와 a+b를 확인해보면 쉽게 알 수 있습니다. >>> re.match('a*b', 'b') # b에는 a가 0개 이상 있으므로 패턴에 매칭됨 <_sre.SRE_Match object; span=(0, 1), match='b'> >>> re.match('a+b', 'b') # b에는 a가 1개 이상 없으므로 패턴에 매칭되지 않음 >>> re.match('a*b', 'aab') # aab에는 a가 0개 이상 있으므로 패턴에 매칭됨 <_sre.SRE_Match object; span=(0, 3), match='aab'> >>> re.match('a+b', 'aab') # aab에는 a가 1개 이상 있으므로 패턴에 매칭됨 <_sre.SRE_Match object; span=(0, 3), match='aab'> a*b, a+b에서 b는 무조건 있어야 하는 문자고, a*는 a가 0개 이상 있어야 하므로 b는 매칭이 됩니다. 하지만 a+는 a가 1개 이상 있어야 하므로 b는 매칭되지 않습니다. 그리고 'ab', 'aab', 'aaab'처럼 a가 0개 이상 또는 1개 이상 있을 때는 a*b와 a+b를 모두 만족합니다. 43.2.1 문자가 한 개만 있는지 판단하기문자가 여러 개 있는지 판단할 때는 *과 +를 사용했지만, 문자가 한 개만 있는지 판단할 때는 어떻게 해야 할까요? 이때는 ?와 .을 사용합니다. ?는 ? 앞의 문자(범위)가 0개 또는 1개인지 판단하고, .은 .이 있는 위치에 아무 문자(숫자)가 1개 있는지 판단합니다.
>>> re.match('abc?d', 'abd') # abd에서 c 위치에 c가 0개 있으므로 패턴에 매칭됨 <_sre.SRE_Match object; span=(0, 3), match='abd'> >>> re.match('ab[0-9]?c', 'ab3c') # [0-9] 위치에 숫자가 1개 있으므로 패턴에 매칭됨 <_sre.SRE_Match object; span=(0, 4), match='ab3c'> >>> re.match('ab.d', 'abxd') # .이 있는 위치에 문자가 1개 있으므로 패턴에 매칭됨 <_sre.SRE_Match object; span=(0, 4), match='abxd'> 43.2.2 문자 개수 판단하기그럼 문자(숫자)가 정확히 몇 개 있는지 판단하고 싶을 수도 있겠죠? 이때는 문자 뒤에 {개수} 형식을 지정합니다. 문자열의 경우에는 문자열을 괄호로 묶고 뒤에 {개수} 형식을 지정합니다.
h{3}은 h가 3개 있는지 판단하고, (hello){3}은 hello가 3개 있는지 판단합니다. >>> re.match('h{3}', 'hhhello') <_sre.SRE_Match object; span=(0, 3), match='hhh'> >>> re.match('(hello){3}', 'hellohellohelloworld') <_sre.SRE_Match object; span=(0, 15), match='hellohellohello'> 특정 범위의 문자(숫자)가 몇 개 있는지 판단할 수도 있습니다. 이때는 범위 [ ] 뒤에 {개수} 형식을 지정합니다.
다음은 휴대전화의 번호 형식에 맞는지 판단합니다. >>> re.match('[0-9]{3}-[0-9]{4}-[0-9]{4}', '010-1000-1000') # 숫자 3개-4개-4개 패턴에 매칭됨 <_sre.SRE_Match object; span=(0, 13), match='010-1000-1000'> >>> re.match('[0-9]{3}-[0-9]{4}-[0-9]{4}', '010-1000-100') # 숫자 3개-4개-4개 패턴에 매칭되지 않음 이 기능은 문자(숫자)의 개수 범위도 지정할 수 있습니다. {시작개수,끝개수} 형식으로 시작 개수와 끝 개수를 지정해주면 특정 개수 사이에 들어가는지 판단합니다.
다음은 일반전화의 번호 형식에 맞는지 판단합니다. >>> re.match('[0-9]{2,3}-[0-9]{3,4}-[0-9]{4}', '02-100-1000') # 2~3개-3~4개-4개 패턴에 매칭됨 <_sre.SRE_Match object; span=(0, 11), match='02-100-1000'> >>> re.match('[0-9]{2,3}-[0-9]{3,4}-[0-9]{4}', '02-10-1000') # 2~3개-3~4개-4개 패턴에 매칭되지 않음 43.2.3 숫자와 영문 문자를 조합해서 판단하기지금까지 숫자 범위만 판단해보았으니 이제 숫자와 영문 문자를 조합해서 판단해보겠습니다. 영문 문자 범위는 a-z, A-Z와 같이 표현합니다.
>>> re.match('[a-zA-Z0-9]+', 'Hello1234') # a부터 z, A부터 Z, 0부터 9까지 1개 이상 있으므로 <_sre.SRE_Match object; span=(0, 9), match='Hello1234'> # 패턴에 매칭됨 >>> re.match('[A-Z0-9]+', 'hello') # 대문자, 숫자는 없고 소문자만 있으므로 패턴에 매칭되지 않음 이처럼 숫자, 영문 문자 범위는 a-zA-Z0-9 또는 A-Z0-9와 같이 붙여 쓰면 됩니다. 그럼 한글은 어떻게 사용할까요? 영문 문자와 방법이 같습니다. 가-힣처럼 나올 수 있는 한글 조합을 정해주면 됩니다.
>>> re.match('[가-힣]+', '홍길동') # 가부터 힣까지 1개 이상 있으므로 패턴에 매칭됨 <_sre.SRE_Match object; span=(0, 3), match='홍길동'> 43.2.4 특정 문자 범위에 포함되지 않는지 판단하기지금까지 정규표현식으로 특정 문자 범위에 포함되는지 살펴보았습니다. 그럼 특정 문자 범위에 포함되지 않는지 판단하려면 어떻게 해야 할까요? 다음과 같이 문자(숫자) 범위 앞에 ^를 붙이면 해당 범위를 제외합니다.
즉, '[^A-Z]+'는 대문자를 제외한 모든 문자(숫자)가 1개 이상 있는지 판단합니다. >>> re.match('[^A-Z]+', 'Hello') # 대문자를 제외. 대문자가 있으므로 패턴에 매칭되지 않음 >>> re.match('[^A-Z]+', 'hello') # 대문자를 제외. 대문자가 없으므로 패턴에 매칭됨 <_sre.SRE_Match object; span=(0, 5), match='hello'> 앞에서 특정 문자열로 시작하는지 판단할 때도 ^를 사용했었는데 문법이 비슷해서 이 부분은 헷갈리기 쉽습니다. 범위를 제외할 때는 '[^A-Z]+'와 같이 [ ] 안에 넣어주고, 특정 문자 범위로 시작할 때는 '^[A-Z]+'와 같이 [ ] 앞에 붙여줍니다. 그래서 다음과 같이 '^[A-Z]+'는 영문 대문자로 시작하는지 판단합니다.
>>> re.search('^[A-Z]+', 'Hello') # 대문자로 시작하므로 패턴에 매칭됨 <_sre.SRE_Match object; span=(0, 1), match='H'> 물론 특정 문자(숫자) 범위로 끝나는지 확인할 때는 정규표현식 뒤에 $를 붙이면 됩니다.
>>> re.search('[0-9]+$', 'Hello1234') # 숫자로 끝나므로 패턴에 매칭됨 <_sre.SRE_Match object; span=(5, 9), match='1234'> 43.2.5 특수 문자 판단하기문자열을 판단할 때 'Hello1234'처럼 평범한 문자열만 판단했습니다. 그런데 정규표현식에 사용하는 특수 문자 *, +, ?, ., ^, $, (, ) [, ], - 등을 판단하려면 어떻게 해야 할까요? 특수 문자를 판단할 때는 특수 문자 앞에 \를 붙이면 됩니다. 단, [ ] 안에서는 \를 붙이지 않아도 되지만 에러가 발생하는 경우에는 \를 붙입니다.
>>> re.search('\*+', '1 ** 2') # *이 들어있는지 판단 <_sre.SRE_Match object; span=(2, 4), match='**'> >>> re.match('[$()a-zA-Z0-9]+', '$(document)') # $, (, )와 문자, 숫자가 들어있는지 판단 <_sre.SRE_Match object; span=(0, 11), match='$(document)'> 지금까지 범위를 지정하면서 a-zA-Z0-9처럼 대소문자와 숫자를 모두 나열했습니다. 이런 방식으로 범위를 정하면 정규표현식이 길어지고 복잡해집니다. 단순히 숫자인지 문자인지 판단할 때는 \d, \D, \w, \W를 사용하면 편리합니다.
>>> re.match('\d+', '1234') # 모든 숫자이므로 패턴에 매칭됨 <_sre.SRE_Match object; span=(0, 4), match='1234'> >>> re.match('\D+', 'Hello') # 숫자를 제외한 모든 문자이므로 패턴에 매칭됨 <_sre.SRE_Match object; span=(0, 5), match='Hello'> >>> re.match('\w+', 'Hello_1234') # 영문 대소문자, 숫자, 밑줄 문자이므로 패턴에 매칭됨 <_sre.SRE_Match object; span=(0, 10), match='Hello_1234'> >>> re.match('\W+', '(:)') # 영문 대소문자, 숫자, 밑줄문자를 제외한 모든 문자이므로 패턴에 매칭됨 <_sre.SRE_Match object; span=(0, 3), match='(:)'> 43.2.6 공백 처리하기이번에는 공백을 처리해보겠습니다. 공백은 ' '처럼 공백 문자를 넣어도 되고, \s 또는 \S로 표현할 수도 있습니다.
>>> re.match('[a-zA-Z0-9 ]+', 'Hello 1234') # ' '로 공백 표현 <_sre.SRE_Match object; span=(0, 10), match='Hello 1234'> >>> re.match('[a-zA-Z0-9\s]+', 'Hello 1234') # \s로 공백 표현 <_sre.SRE_Match object; span=(0, 10), match='Hello 1234'> 참고 | 같은 정규표현식 패턴을 자주 사용할 때 매번 match나 search 함수에 정규표현식 패턴을 지정하는 방법은 비효율적입니다. 같은 패턴을 자주 사용할 때는 compile 함수를 사용하여 정규표현식 패턴을 객체로 만든 뒤 match 또는 search 메서드를 호출하면 됩니다. 객체 = re.compile('패턴') 객체.match('문자열') 객체.search('문자열') >>> p = re.compile('[0-9]+') # 정규표현식 패턴을 객체로 만듦 >>> p.match('1234') # 정규표현식 패턴 객체에서 match 메서드 사용 <_sre.SRE_Match object; span=(0, 4), match='1234'> >>> p.search('hello') # 정규표현식 패턴 객체에서 search 메서드 사용 |