Python

정규표현식(1) [Python]

JEO96 2022. 11. 16. 12:45
반응형

 

 

정규표현식

더하기 기호(+)는 최소 1개 이상의 문자를 의미한다.

ex) ab+c

abc
abbc
abbbc
...

곱하기 기호(*)는 더하기 기호와 비슷하지만 0개의 경우도 포함한다.

ex) ab*c

ac
abc
abbc
abbbc
...

전화번호를 검증하는 함수를 함수를 작성해보자. 숫자를 의미하는 #을 사용하는 경우 다음과 같이 패턴을 작성할 수도 있다.

###-###-####

정규표현식 문법으로는 다음과 같이 작성할 수 있다.

\d\d\d-\d\d\d-\d\d\d\d

이 경우 역스리시(\)는 이스케이프 시퀀스로 동작하지만 d를 리터럴 문자로 만들지 않고, 특별한 의미를 부여한다.

부분표현식 \d는 하나의 숫자와 일치하는 것을 의미한다. 다음 부분표현식으로도 숫자를 표현할 수 있다.

[0-9]

반면 \d는 5글자가 아니라 2글자라 더 간결한다.

다음은 전화번호를 검증하는 정규표현식 패터을 구현한 완전판 파이썬 프로그램이다.

import re	# 정규표현식 패키지
pattern = r'\d\d\d-\d\d\d-\d\d\d\d$'	# 앞부분만 일치하여도 정답으로 인식하는 것을 방지하기 위해 $를 추가함

s = input('Enter tel. number: ')
if re.match(pattern, s):
	print('Number accepted.')
else:
	print(Incorrect format.')

555-123-5000과 555 123 5000 둘다 정답으로 인식하게 할 경우 패턴을 r'\d\d\d[ -]\d\d\d[ -]\d\d\d\d$'로 수정하면 빼기 기호(-)를 공백으로 대신 사용하여도 정답으로 인식한다.

 

대소문자 무시하고 싶을땐 정규식 표현 플래그에서 IGNORECASE 플래그를 사용하면 된다.

if re.match('m*ack', Mack the Knife', re.IGNORECASE):
	print('Success.')

if re.match('m*ack', Mack the Knife', re.I): #  re.I는 re.IGNORECASE의 약어
	print('Success.')

정규표현식 플래그를 2개 이상 사용할 경우 OR 연산자(|)를 사용하여 조합할 수도 있다.

if re.match('m*ack', Mack the Knife', re.I | re.DEBUG):
	print('Success.')

정규표현식 플래그

플래그 약어 설명
ASCII A 아스키(ASCII) 설정으로 가정한다.
IGNORECASE I 모든 '검색'과 '일치'는 대소문자를 구분하지 않는다.
DEBUG   IDLE 안에서 연산이 실행되면 디버깅 정보가 출력된다.
LOCALE L 문자숫자식, 단어 경계와 숫자에 로케일(LOCALE) 설정을 반영하여 일치를 찾는다.
MULTILINE M 문자열의 시작과 끝처럼 특수 문자 ^와 $는 줄의 시작과 끝을 의미한다.
DOTALL S 점 기호(.)는 모든 문자와 일치한다. 개행 문자(\n)도 포함된다.
UNICODE U 문자숫자식, 단어 경계와 숫자가 유니코드(UNICODE)라는 가정하에 일치를 찾는다.
VERBOSE X 문자 클래스의 일부가 아닌 이상 패턴 안의 빈칸은 무시된다. 코드에 표현식을 더 보기 좋게 작성하는 데 사용한다.

메타 문자

특수 문자나 문자의 숫자를 제어하는 문자를 위한 도구다. 각 문자는 한 번에 하나의 문자와 일치한다.

특수 문자 이름/설명
. 점기호. 개행 문자를 제외한 임의의 문자 하나와 일치한다. DATALL 플래그가 주어지면 모든 문자와 일치할 수 있다.
^ 캐럿 기호. 문자열의 시작을 의미한다. MULTILINE 플래그가 주어지면 줄의 시작을 의미할 수 있다(개행 문자 뒤의 모든 문자).
$ 문자열의 끝을 의미한다. MULTILINE 플래그가 주어지면 줄의 끝을 의미한다(개행 문자 혹은 문자열 끝에서 바로 앞에 위치한 마지막 문자).
\A 문자열의 시작을 의미한다.
\b 단어의 경계. 예를 들어 r'ish\b'는 'ish is'와 'ish)'와 일치하지만 'ishmael'과는 일치하지 않는다.
\B 비단어(nonword)의 경계. 이 지점에서 새로운 단어가 시작되지 않는 ㅕㅇ우에만 일치한다. 예를 들어 r'al\B'는 'always'와 일치하지만 'al '과는 일치하지 않는다.
\d 모든 숫자. 0부터 9까지의 숫자를 포함한다. UNICODE 플래그가 설정되면 숫자로 분류된 유니코드 문자도 포함된다.
\s 모든 여백(whitespace) 문자. 빈칸이나 \t, \n, \r, \f, \v 등이 포함된다. UNICODE와 LOCALE 플래그가 설정되면 여백 문자 판단 기준이 변경될 수도 있다.
\S 위에서 정의한 여백 문자가 아닌 모든 문자
\w 몯느 문자숫자식 문자 (글자 혹은 숫자) 혹은 언더스코어 기호(_)와 일치한다. UNICODE와 LOCALE 플래그가 설정되면 문자숫자식 판단 기준이 변경될 수도 있다.
\W 위에서 정의한 문자숫자식 문자를 제외한 모든 문자
\z 문자열 끝을 의미한다.

문자 집합

[문자_집합]

[문자_집합] 	// 집합 안에 하나의 문자와 일치한다.
[^문자_집합]	// 집합 안에 존재하지 않은 하나의 문자와 일치한다.

r'c[aeiou]t'는 다음 단어들과 일치한다.

cat
cet
cit
cot
cut

c[aeiou]+t와 같이 문자집합과 연산자를 사용하여 표현할 수 있다.

빼기 기호(-)를 사용하여 범위를 지정할 수 있다.

[a-n]: a부터 n까지를 의미

패턴 수량자

정규표현식 수량자

구문 설명
expr* expr 표현식이 한 번만 나타나는 대신 나타나지 않을 수도 있고, 여러 번 나타날 수도 있다. 가령 a*는 'a', 'aa', 'aaa'와 일치하며, 빈 문자열과도 일치한다.
expr+ expr 표현식이 한 번 이상 나타날 수 있다. 가령 a+는 'a', 'aa', 'aaa'와 일치한다.
expr? expr ㅍ현식은 나타나지 않거나 한 번만 나타나야 한다. 가령 a?는 'a'혹은 빈 문자열과 일치한다.
expr1 | expr2 둘 중 하나만 선택(alternation). expr1이 한 번만 나타나거나 expr2가 한 번만 나타나야 한다. 둘다 나타나면 안 된다. 가령 a|b는 'a' 혹은 'b'와 일치한다. 이 연산자의 우선순위가 매우 낮기 때문에 예를 들dj cat|dog는 cat 혹은 dog와 일치한다.
expr{n} expr 표현식이 정확히 n번 나타난다. 가령 a{3}은 'aaa'와 일치하지만 sa{3}d는 saaad'와 일치하는 반면, 'saaaaaad'와는 일치하지 않는다.
expr{m, n} expr 표현식이 최소 m번, 최대 n번 나타날 수 있다. 가령 x{2,4}y는 'xxy', 'xxxy', 'xxxy'와는 일치하지만 "xxxxxxy"나 "xy"와는 일치하지 않는다.
expr{m,} expr 표현식이 최소 m번 이상 나타나야 하지만 최대 출현 횟수의 제한은 없다. 가령 x{3,}은 패턴'xxx'가 나타나는지 확인하며, 세 번 이상 나타나도 ㅗ딘다. 따라서 zx(3,)y는 'zxxxxxy'와 일치한다.
expr{,n} expr 표현식이 나타나지 않아도 되지만, 최대 n번까지 나타날 수 있다. 가령 ca{,2}t는 "ct", "cat", "caat"와 일치하지만 "caaat"와는 일치하지 않는다.
(expr) 정규표현식 검사기가 expr을 하나의 그룹으로 인식한다. 이 기능이 필요한 이유는 두 가지다. 첫 번째, 수량자는 바로 앞에 있는 표현식에만 적용되지만, 표현식이 그룹인 경우 그룹 자체에 적용된다. 가련 (ab)+는 'ab', 'abab', 'ababab'와 일치한다.
두 번째, 나중에 그룹 단위로 일치 유무를 판단하거나 텍스트를 교체하기 위해 다시 참조될 수 있기 때문에 그룹을 명시하는 것이 중요하다.
\n 일치된 그룹을 참조한다. 참조는 실제로 실행 시간에 찾는다. 단순히 해당 패턴 자체를 반복하지는 않는다. \1은 첫 번째 그룹을 참조하며, \2는 두 번째 그룹을 참조한다.

패턴 수량자를 사용하면 앞에서 전화번호를 표현했던 r'\d\d\d-\d\d\d-\d\d\d\d'를 r'\d{3}-\d{3}-\d{4}와 같이 수정할 수 있다.

반응형

'Python' 카테고리의 다른 글

정규표현식(3) [Python]  (0) 2022.11.28
정규표현식(2) [Python]  (0) 2022.11.17
리스트 복사 vs 리스트 변수 복사, 얕은 복사 vs 깊은 복사  (0) 2022.11.15
str 불리언(is) 메서드[Python]  (0) 2022.11.11
set(세트)[Python]  (0) 2022.11.11