`re` — 정규 표현식 연산

re — 정규 표현식 연산

re 모듈은 Perl에서 볼 수 있는 것과 비슷한 정규 표현식 매칭 연산을 제공해요.

패턴과 검색 대상 문자열 모두 유니코드 문자열(str)이 될 수도 있고 8비트 문자열(bytes)이 될 수도 있어요. 하지만 유니코드 문자열과 8비트 문자열은 섞을 수 없어요. 즉 bytes 패턴으로 유니코드 문자열을 매칭하거나 그 반대는 불가능해요. 마찬가지로 치환을 요청할 때 치환 문자열은 패턴과 검색 문자열 양쪽과 같은 타입이어야 해요.

정규 표현식은 백슬래시 문자('\')를 사용해 특수 형식을 나타내거나 특수 문자를 그 특수 의미를 발동시키지 않고 쓰게 해요. 이는 문자열 리터럴에서 같은 목적으로 같은 문자를 쓰는 Python의 사용과 충돌해요. 예를 들어 리터럴 백슬래시를 매칭하려면 패턴 문자열로 '\\\\'를 써야 할 수 있는데, 정규 표현식은 \\여야 하고 각 백슬래시는 일반 Python 문자열 리터럴 안에서 \\로 표현돼야 하기 때문이에요. 또한 Python의 문자열 리터럴 백슬래시 사용에서 잘못된 이스케이프 시퀀스는 이제 SyntaxWarning을 발생시키고 나중에는 SyntaxError가 될 거라는 점도 기억하세요. 이 동작은 정규 표현식에 유효한 이스케이프 시퀀스여도 일어나요.

해결책은 정규 표현식 패턴에 Python의 raw 문자열 표기를 쓰는 거예요. 'r'로 접두사가 붙은 문자열 리터럴에서는 백슬래시가 특별한 방식으로 처리되지 않아요. 그래서 r"\n"'\''n'을 담은 두 문자 문자열인 반면, "\n"은 줄바꿈을 담은 한 문자 문자열이에요. 보통 패턴은 Python 코드에서 이 raw 문자열 표기로 표현돼요.

대부분의 정규 표현식 연산은 모듈 수준 함수와 컴파일된 정규 표현식의 메서드로 모두 제공된다는 점을 기억하는 게 중요해요. 함수는 먼저 정규식 객체를 컴파일하지 않아도 되는 단축키지만 몇몇 미세 조정 매개변수를 놓쳐요.

출처: Python 표준 라이브러리

본문

정규 표현식 문법 (Regular Expression Syntax)

정규 표현식(또는 RE)은 그에 매칭되는 문자열의 집합을 지정해요. 이 모듈의 함수는 특정 문자열이 주어진 정규 표현식에 매칭되는지 확인하게 해줘요. 정규 표현식은 이어붙여 새 정규 표현식을 만들 수 있어요. AB가 모두 정규 표현식이면 AB도 정규 표현식이에요. 복잡한 표현식은 여기 설명하는 것 같은 더 단순한 원시 표현식에서 쉽게 구성할 수 있어요.

정규 표현식은 특수 문자와 보통 문자를 모두 포함할 수 있어요. 'A', 'a', '0' 같은 대부분의 보통 문자는 가장 단순한 정규 표현식으로, 그냥 자기 자신과 매칭돼요. last'last' 문자열에 매칭되는 식으로 보통 문자를 이어붙일 수 있어요.

'|'이나 '(' 같은 일부 문자는 특수해요. 특수 문자는 보통 문자의 클래스를 나타내거나 그 주변 정규 표현식이 해석되는 방식을 바꿔요.

반복 연산자나 수량자(*, +, ?, {m,n} 등)는 직접 중첩할 수 없어요. 이는 비탐욕(non-greedy) 수식어 접미사 ?와의 모호함을 피해요. 내부 반복에 두 번째 반복을 적용하려면 괄호를 쓸 수 있어요. 예를 들어 (?:a{6})* 표현식은 여섯 개 'a' 문자의 어떤 배수든 매칭해요.

특수 문자들:

  • . (점): 기본 모드에서 줄바꿈을 제외한 어떤 문자와도 매칭돼요. DOTALL 플래그가 지정되면 줄바꿈을 포함한 어떤 문자와도 매칭돼요. (?s:.)는 플래그와 무관하게 어떤 문자와도 매칭돼요.
  • ^ (캐럿): 문자열의 시작과 매칭되고, MULTILINE 모드에서는 각 줄바꿈 직후에도 매칭돼요.
  • $: 문자열의 끝 또는 문자열 끝의 줄바꿈 직전과 매칭되고, MULTILINE 모드에서는 줄바꿈 앞에서도 매칭돼요. foo는 'foo'와 'foobar' 둘 다 매칭하지만 foo$는 'foo'만 매칭해요.
  • *: 앞의 RE가 0회 이상, 가능한 한 많이 반복되게 해요. ab*는 'a', 'ab', 'a' 뒤에 임의 개수의 'b'를 매칭해요.
  • +: 앞의 RE가 1회 이상 반복되게 해요. ab+는 'a' 뒤에 0이 아닌 개수의 'b'를 매칭하고 'a'만은 매칭하지 않아요.
  • ?: 앞의 RE가 0회 또는 1회 반복되게 해요. ab?는 'a' 또는 'ab'를 매칭해요.
  • *?, +?, ??: '*', '+', '?' 수량자는 모두 탐욕적(greedy)이라 가능한 한 많은 텍스트를 매칭해요. ?를 수량자 뒤에 붙이면 비탐욕적 또는 최소 방식으로 수행돼 가능한 한 적은 문자를 매칭해요. RE <.*>'<a> b <c>'에 매칭하면 전체 문자열을 매칭하지만, <.*?>'<a>'만 매칭해요.
  • *+, ++, ?+: '+'가 붙은 것들도 가능한 한 많이 매칭하지만, 진짜 탐욕 수량자와 달리 뒤의 표현식이 매칭에 실패할 때 되추적(back-tracking)을 허용하지 않아요. 이를 소유적(possessive) 수량자라고 해요. a*+a를 'aaaa'에 매칭하면 a*+가 4개 'a'를 모두 매칭하지만 마지막 'a'가 더 이상 매칭할 문자를 못 찾으면 되추적할 수 없어 실패해요. x*+, x++, x?+는 각각 (?>x*), (?>x+), (?>x?)와 동등해요. 버전 3.11에서 추가.
  • {m}: 앞의 RE가 정확히 m 번 매칭되도록 지정해요. a{6}은 정확히 여섯 개의 'a'를 매칭하지만 다섯 개는 매칭하지 않아요.
  • {m,n}: 앞의 RE가 m에서 n 번 매칭되게 해요. m을 생략하면 하한 0, n을 생략하면 무한 상한을 지정해요. a{4,}b는 'aaaab' 또는 천 개의 'a' 뒤 'b'를 매칭하지만 'aaab'는 매칭하지 않아요.
  • {m,n}?: 앞의 RE가 m에서 n 번, 가능한 한 적게 매칭되게 해요. 이전 수량자의 비탐욕 버전이에요. 6-문자 'aaaaaa'에서 a{3,5}는 5개의 'a'를, a{3,5}?는 3개만 매칭해요.
  • {m,n}+: 앞의 RE가 m에서 n 번, 되추적 지점을 만들지 않고 가능한 한 많이 매칭되게 해요. 소유적 버전이에요. 버전 3.11에서 추가.
  • \: 특수 문자를 이스케이프하거나(그래서 '*', '?' 등과 매칭 가능) 특수 시퀀스를 알리거나 해요. raw 문자열을 쓰지 않으면 Python이 문자열 리터럴에서도 백슬래시를 이스케이프 시퀀스로 쓴다는 점을 기억하세요. 가장 단순한 표현식을 빼고는 raw 문자열을 쓰는 게 좋아요.
  • []: 문자 집합을 나타내는 데 씁니다. [amk]는 'a', 'm', 'k'를 매칭해요. [a-z]는 소문자 ASCII 문자, [0-9A-Fa-f]는 어떤 16진수 자리와도 매칭돼요. 특수 문자는 백슬래시를 빼고 집합 안에서 특수 의미를 잃어요. 집합의 첫 문자가 '^'이면 집합에 없는 모든 문자와 매칭돼요. [^5]는 '5'를 제외한 어떤 문자와도 매칭돼요. 집합 안에서 리터럴 ']'를 매칭하려면 백슬래시를 앞에 붙이거나 집합의 시작에 놓아요.
  • |: A|BA 또는 B와 매칭되는 정규 표현식을 만들어요. 리터럴 '|'를 매칭하려면 \|[|]를 쓰세요.
  • (...): 괄호 안의 어떤 정규 표현식이든 매칭하고 그룹의 시작과 끝을 나타내요. 그룹의 내용은 매칭이 수행된 뒤 검색할 수 있고, 아래 설명하는 \number 특수 시퀀스로 문자열에서 나중에 매칭할 수 있어요.
  • (?...): 확장 표기법이에요. '?' 다음 첫 문자는 구성의 의미와 추가 문법을 결정해요.
    • (?aiLmsux): 빈 문자열과 매칭되고, 문자들이 전체 정규 표현식에 대응 플래그를 설정해요: re.A(ASCII 전용), re.I(대소문자 무시), re.L(로케일 의존), re.M(멀티라인), re.S(점이 모두 매칭), re.U(유니코드), re.X(verbose). 버전 3.11 변경: 이 구성은 표현식의 시작에서만 쓸 수 있음.
    • (?:...): 일반 괄호의 비캡처 버전이에요. 괄호 안의 어떤 정규 표현식이든 매칭하지만, 그룹이 매칭한 부분 문자열은 검색할 수 없고 이후 패턴에서 참조할 수 없어요.
    • (?P<name>...): 이름 있는 그룹이에요. 그룹 이름은 유효한 Python 식별자여야 하며 각 이름은 정규 표현식 안에서 한 번만 정의돼야 해요.
    • (?P=name): 이름 있는 그룹에 대한 역참조로, 이전에 name으로 매칭된 텍스트와 매칭돼요.
    • (?#...): 주석으로, 괄호의 내용은 무시돼요.
    • (?=...): ...이 다음에 매칭되면 매칭되지만 문자열을 소비하지 않아요. 이를 긍정 전방 탐색 어서션(lookahead assertion)이라고 해요. Isaac (?=Asimov)'Asimov'가 뒤따를 때만 'Isaac '을 매칭해요.
    • (?!...): ...이 다음에 매칭되지 않으면 매칭돼요. 부정 전방 탐색 어서션이에요.
    • (?<=...): 문자열의 현재 위치가 현재 위치에서 끝나는 ...의 매칭이 앞에 올 때 매칭돼요. 긍정 후방 탐색 어서션이에요. (?<=abc)def'abcdef'에서 매칭을 찾아요. 포함된 패턴은 고정 길이의 문자열만 매칭해야 해요(abca|b는 허용되지만 a*, a{3,4}는 안 됨). 긍정 후방 탐색 어서션으로 시작하는 패턴은 검색 문자열의 시작에서는 매칭하지 않으니 match()보다 search()를 쓸 가능성이 높아요.
    • (?<!...): 문자열의 현재 위치가 ...의 매칭이 앞에 오지 않을 때 매칭돼요. 부정 후방 탐색 어서션이에요.
    • (?(id/name)yes-pattern|no-pattern): 주어진 idname의 그룹이 존재하면 yes-pattern으로, 없으면 no-pattern으로 매칭을 시도해요.

특수 시퀀스는 '\'와 아래 목록의 문자로 구성돼요:

  • \number: 같은 번호의 그룹 내용과 매칭돼요. 그룹은 1부터 번호가 매겨져요. (.+) \1은 'the the'나 '55 55'를 매칭하지만 'thethe'는 매칭하지 않아요(그룹 뒤의 공백에 주의). 이 특수 시퀀스는 처음 99개 그룹 중 하나만 매칭하는 데 쓸 수 있어요.
  • \A: 문자열의 시작에서만 매칭돼요.
  • \b: 빈 문자열과 매칭되지만 단어의 시작이나 끝에서만요. r'\bat\b'는 'at', 'at.', '(at)', 'as at ay'를 매칭하지만 'attempt'나 'atlas'는 매칭하지 않아요. 유니코드(str) 패턴의 기본 단어 문자는 유니코드 영숫자와 밑줄이고, ASCII 플래그로 바꿀 수 있어요. 문자 범위 안에서 \b는 Python 문자열 리터럴과의 호환을 위해 백스페이스 문자를 나타내요.
  • \B: 빈 문자열과 매칭되지만 단어의 시작이나 끝에 있지 않을 때만이에요. \b의 반대예요. r'at\B'는 'athens', 'atom', 'attorney'는 매칭하지만 'at', 'at.', 'at!'는 매칭하지 않아요. 버전 3.14 변경: \B가 이제 빈 입력 문자열과도 매칭됨.
  • \d: 유니코드(str) 패턴에서는 어떤 유니코드 십진 자리(Unicode [Nd] 범주)와도 매칭돼요. [0-9]와 그 외 많은 자리 문자를 포함해요. ASCII 플래그를 쓰면 [0-9]와 매칭돼요. 8비트(bytes) 패턴에서는 ASCII 문자 집합의 어떤 십진 자리([0-9])와도 매칭돼요.
  • \D: 십진 자리가 아닌 어떤 문자와도 매칭돼요. \d의 반대예요. ASCII 플래그를 쓰면 [^0-9]와 매칭돼요.
  • \s: 유니코드(str) 패턴에서는 유니코드 공백 문자(str.isspace()가 정의하는 대로)와 매칭돼요. [ \t\n\r\f\v]와 많은 언어의 타이포그래피 규칙이 요구하는 줄바꿈 없는 공백 같은 다른 문자들을 포함해요. bytes 패턴에서는 [ \t\n\r\f\v]와 동등해요.
  • \S: 공백 문자가 아닌 어떤 문자와도 매칭돼요. \s의 반대예요.
  • \w: 유니코드(str) 패턴에서는 유니코드 단어 문자와 매칭돼요. 모든 유니코드 영숫자(str.isalnum()이 정의)와 밑줄(_)을 포함해요. ASCII 플래그를 쓰면 [a-zA-Z0-9_]와 매칭돼요. bytes 패턴은 [a-zA-Z0-9_]와 동등해요.
  • \W: 단어 문자가 아닌 어떤 문자와도 매칭돼요. \w의 반대예요.
  • \z: 문자열의 끝에서만 매칭돼요. 버전 3.14에서 추가.
  • \Z: \z와 같아요. 이전 Python 버전과의 호환용이에요.

Python 문자열 리터럴이 지원하는 대부분의 이스케이프 시퀀스(\a, \b, \f, \n, \N, \r, \t, \u, \U, \v, \x, \\)도 정규 표현식 파서가 받아들여요. '\u', '\U', '\N' 이스케이프는 유니코드(str) 패턴에서만 인식되고 bytes 패턴에서는 오류예요. 알려지지 않은 ASCII 문자 이스케이프는 미래 사용을 위해 예약되고 오류로 처리돼요.

모듈 내용 (Module Contents)

이 모듈은 여러 함수, 상수, 예외를 정의해요.

플래그 (Flags)

버전 3.6 변경: 플래그 상수가 이제 enum.IntFlag의 하위 클래스인 RegexFlag의 인스턴스가 됨.

class re.RegexFlag

아래 나열된 regex 옵션을 담은 enum.IntFlag 클래스예요.

  • re.A, re.ASCII: \w, \W, \b, \B, \d, \D, \s, \S가 전체 유니코드 대신 ASCII 전용 매칭을 수행하게 해요. 유니코드(str) 패턴에서만 의미 있고 bytes 패턴에서는 무시돼요. 인라인 플래그 (?a)에 대응.
  • re.DEBUG: 컴파일된 표현식에 대한 디버그 정보를 표시해요.
  • re.I, re.IGNORECASE: 대소문자를 무시하는 매칭을 수행해요. [A-Z] 같은 표현식이 소문자도 매칭하게 돼요. ASCII 플래그로 비ASCII 매칭을 비활성화하지 않는 한 Üü에 매칭되는 것 같은 전체 유니코드 매칭도 동작해요. 인라인 플래그 (?i)에 대응.
  • re.L, re.LOCALE: \w, \W, \b, \B와 대소문자 무시 매칭을 현재 로케일에 의존하게 해요. bytes 패턴에서만 쓸 수 있어요. 이 플래그는 권장되지 않아요. 로케일 메커니즘은 한 번에 하나의 "문화"만 다루고 8비트 로케일에서만 동작해서 매우 신뢰할 수 없거든요. 대신 유니코드 매칭을 고려하세요.
  • re.M, re.MULTILINE: 지정하면 '^'가 문자열의 시작과 각 줄의 시작(각 줄바꿈 직후)에서 매칭되고, '$'가 문자열의 끝과 각 줄의 끝(각 줄바꿈 직전)에서 매칭돼요. 기본적으로 '^'는 문자열의 시작에서만, '$'는 문자열의 끝(그리고 끝의 줄바꿈 직전)에서만 매칭돼요. 인라인 플래그 (?m)에 대응.
  • re.NOFLAG: 적용된 플래그가 없음을 나타내고 값은 0이에요. 함수 키워드 인자의 기본값이나 다른 플래그와 조건부로 OR될 기본 값으로 쓸 수 있어요. 버전 3.11에서 추가.
  • re.S, re.DOTALL: '.' 특수 문자가 줄바꿈을 포함한 어떤 문자와도 매칭하게 해요. 이 플래그가 없으면 '.'는 줄바꿈을 제외한 어떤 것이든 매칭해요. 인라인 플래그 (?s)에 대응.
  • re.U, re.UNICODE: Python 3에서 str 패턴은 기본적으로 유니코드 문자를 매칭하므로 이 플래그는 효과 없이 중복돼요. 하위 호환을 위해서만 유지돼요. re.X, re.VERBOSE: 패턴의 논리적 섹션을 시각적으로 분리하고 주석을 추가할 수 있게 해서 더 보기 좋고 읽기 쉬운 정규 표현식을 쓸 수 있게 해요. 패턴 안의 공백은 문자 클래스에 있거나 이스케이프되지 않은 백슬래시가 앞에 오거나 *?, (?:, (?P<...> 같은 토큰 안에 있지 않으면 무시돼요. 문자 클래스에 없고 이스케이프되지 않은 백슬래시가 앞에 오지 않는 #가 줄에 있으면 그런 가장 왼쪽 #부터 줄 끝까지의 모든 문자는 무시돼요. 인라인 플래그 (?x)에 대응.

함수 (Functions)

re.compile(*pattern*, *flags=0*)

정규 표현식 패턴을 정규 표현식 객체로 컴파일해요. flags 값을 지정해 표현식의 동작을 수정할 수 있어요. 값은 비트 OR(| 연산자)로 결합한 어떤 플래그 변수든 될 수 있어요. 다음 시퀀스는

prog = re.compile(pattern)
result = prog.match(string)

다음과 동등해요.

result = re.match(pattern, string)

하지만 표현식을 한 프로그램에서 여러 번 쓸 때는 re.compile()을 쓰고 결과 정규 표현식 객체를 재사용하는 게 더 효율적이에요. 최근 패턴의 컴파일된 버전은 캐시되므로, 한 번에 몇 개의 정규 표현식만 쓰는 프로그램은 컴파일에 신경 쓸 필요가 없어요.

re.search(*pattern*, *string*, *flags=0*)

string을 훑어 정규 표현식 pattern이 매치를 만드는 첫 위치를 찾고 대응하는 Match를 반환해요. 문자열의 어떤 위치도 패턴과 매칭하지 않으면 None을 반환해요. 이는 문자열 어딘가의 0 길이 매치를 찾는 것과 다르다는 점에 주의하세요.

re.match(*pattern*, *string*, *flags=0*)

string시작에 있는 0개 이상의 문자가 정규 표현식 pattern과 매칭되면 대응하는 Match를 반환해요. 문자열이 패턴과 매칭하지 않으면 None을 반환해요. MULTILINE 모드에서도 re.match()는 문자열의 시작에서만 매칭하고 각 줄의 시작에서는 매칭하지 않는다는 점에 주의하세요. 문자열 아무 데나 매치를 찾으려면 search()를 쓰세요.

re.fullmatch(*pattern*, *string*, *flags=0*)

전체 string이 정규 표현식 pattern과 매칭되면 대응하는 Match를 반환해요. 매칭하지 않으면 None을 반환해요. 버전 3.4에서 추가.

re.split(*pattern*, *string*, *maxsplit=0*, *flags=0*)

stringpattern이 나타나는 곳으로 나눠요. pattern에 캡처 괄호를 쓰면 패턴의 모든 그룹 텍스트도 결과 목록의 일부로 반환돼요. maxsplit이 0이 아니면 최대 maxsplit번 분할이 일어나고 문자열 나머지가 목록의 마지막 요소로 반환돼요.

>>> re.split(r'\W+', 'Words, words, words.')
['Words', 'words', 'words', '']
>>> re.split(r'(\W+)', 'Words, words, words.')
['Words', ', ', 'words', ', ', 'words', '.', '']
>>> re.split(r'\W+', 'Words, words, words.', maxsplit=1)
['Words', 'words, words.']
>>> re.split('[a-f]+', '0a3B9', flags=re.IGNORECASE)
['0', '3', '9']

구분자에 캡처 그룹이 있고 문자열의 시작에서 매칭되면 결과는 빈 문자열로 시작해요. 이 방식으로 구분자 구성 요소는 항상 결과 목록에서 같은 상대 인덱스에 있어요. 인접한 빈 매치는 불가능하지만, 비어 있지 않은 매치 직후에 빈 매치가 나타날 수 있어요. 버전 3.13부터 maxsplitflags를 위치 인자로 넘기는 것은 폐기됨.

re.findall(*pattern*, *string*, *flags=0*)

string에서 pattern의 겹치지 않는 모든 매치를 문자열 또는 튜플의 목록으로 반환해요. string은 왼쪽에서 오른쪽으로 훑고 매치는 발견된 순서로 반환돼요. 빈 매치는 결과에 포함돼요. 결과는 패턴의 캡처 그룹 수에 따라 달라져요. 그룹이 없으면 전체 패턴과 매칭되는 문자열 목록, 그룹이 정확히 하나면 그 그룹과 매칭되는 문자열 목록, 여러 그룹이 있으면 그룹과 매칭되는 문자열 튜플 목록을 반환해요. 비캡처 그룹은 결과의 형태에 영향을 주지 않아요.

>>> re.findall(r'\bf[a-z]*', 'which foot or hand fell fastest')
['foot', 'fell', 'fastest']
>>> re.findall(r'(\w+)=(\d+)', 'set width=20 and height=10')
[('width', '20'), ('height', '10')]

re.finditer(*pattern*, *string*, *flags=0*)

RE pattern의 모든 겹치지 않는 매치에 대해 Match 객체를 만드는 이터레이터를 반환해요. string은 왼쪽에서 오른쪽으로 훑고 매치는 발견된 순서로 반환돼요. 빈 매치는 결과에 포함돼요.

re.sub(*pattern*, *repl*, *string*, *count=0*, *flags=0*)

string에서 pattern의 가장 왼쪽 겹치지 않는 발생을 치환 repl로 바꾼 문자열을 반환해요. 패턴을 찾지 못하면 string이 바뀌지 않은 채 반환돼요. repl은 문자열 또는 함수일 수 있어요. 문자열이면 그 안의 백슬래시 이스케이프가 처리돼요. \n은 새 줄로, \r은 캐리지 리턴으로 변환되는 식이에요. \6 같은 역참조는 패턴의 6번 그룹이 매칭한 부분 문자열로 바뀌어요. 예를 들어:

>>> re.sub(r'def\s+([a-zA-Z_][a-zA-Z_0-9]*)\s*\(\s*\):',
...        r'static PyObject*\npy_\1(void)\n{',
...        'def myfunc():')
'static PyObject*\npy_myfunc(void)\n{'

repl이 함수면 pattern의 겹치지 않는 매번 발생마다 호출돼요. 함수는 단일 Match 인자를 받고 치환 문자열을 반환해요. 예를 들어:

>>> def dashrepl(matchobj):
...     if matchobj.group(0) == '-': return ' '
...     else: return '-'
...
>>> re.sub('-{1,2}', dashrepl, 'pro----gram-files')
'pro--gram files'
>>> re.sub(r'\sAND\s', ' & ', 'Baked Beans And Spam', flags=re.IGNORECASE)
'Baked Beans & Spam'

선택 인자 count는 바꿀 패턴 발생의 최대 수예요. 생략하거나 0이면 모든 발생이 바뀌어요. 문자열 타입 repl 인자에서는 \g<name>(?P<name>...) 문법으로 정의된 name 그룹이 매칭한 부분 문자열을 사용하고, \g<number>는 해당 그룹 번호를 사용해요. \g<0> 역참조는 RE가 매칭한 전체 부분 문자열을 대체해요. 버전 3.13부터 countflags를 위치 인자로 넘기는 것은 폐기됨.

re.subn(*pattern*, *repl*, *string*, *count=0*, *flags=0*)

sub()와 같은 연산을 수행하지만 튜플 (new_string, number_of_subs_made)을 반환해요.

re.escape(*pattern*)

pattern의 특수 문자를 이스케이프해요. 정규 표현식 메타문자를 가질 수 있는 임의 리터럴 문자열을 매칭하고 싶을 때 유용해요. 예를 들어:

>>> print(re.escape('https://www.python.org'))
https://www\.python\.org

이 함수는 sub()subn()의 치환 문자열에는 쓰면 안 돼요. 오직 백슬래시만 이스케이프해야 하거든요. 버전 3.7 변경: 정규 표현식에서 특수 의미를 가질 수 있는 문자만 이스케이프됨.

re.purge()

정규 표현식 캐시를 지워요.

예외 (Exceptions)

exception re.PatternError(*msg*, *pattern=None*, *pos=None*)

여기 함수 중 하나에 넘긴 문자열이 유효한 정규 표현식이 아닐 때(예: 짝이 안 맞는 괄호 포함)나 컴파일·매칭 중 다른 오류가 발생할 때 발생하는 예외예요. 문자열이 패턴에 대한 매치를 포함하지 않는 것은 결코 오류가 아니에요. 인스턴스에는 msg(형식화되지 않은 오류 메시지), pattern(정규 표현식 패턴), pos(컴파일이 실패한 pattern의 인덱스), lineno, colno 속성이 있어요. 버전 3.13 변경: 원래 이름은 error였고, 하위 호환을 위해 별칭으로 유지됨.

정규 표현식 객체 (Regular Expression Objects)

class re.Pattern

re.compile()이 반환하는 컴파일된 정규 표현식 객체예요. 패턴은 처리하는 문자열 타입(str 또는 bytes)에 대해 제네릭이에요.

  • Pattern.search(string[, pos[, endpos]]): 문자열에서 이 정규 표현식이 매치를 만드는 첫 위치를 찾고 대응하는 Match를 반환해요. None이면 매치가 없다는 뜻이에요. pos는 검색을 시작할 인덱스(기본 0), endpos는 검색 한도를 제한해요.
  • Pattern.match(string[, pos[, endpos]]): 문자열 시작에 있는 0개 이상의 문자가 이 정규 표현식과 매칭되면 해당 Match를 반환해요.
  • Pattern.fullmatch(string[, pos[, endpos]]): 전체 문자열이 매칭되면 해당 Match를 반환해요. 버전 3.4에서 추가.
  • Pattern.split(string, maxsplit=0): 컴파일된 패턴을 쓴 split() 함수와 동일.
  • Pattern.findall(string[, pos[, endpos]]): 컴파일된 패턴을 쓴 findall() 함수와 비슷하지만 search()처럼 검색 영역을 제한하는 pos, endpos도 받아요.
  • Pattern.finditer(string[, pos[, endpos]]): finditer() 함수와 비슷하지만 pos, endpos도 받아요.
  • Pattern.sub(repl, string, count=0), Pattern.subn(repl, string, count=0): 컴파일된 패턴을 쓴 각각의 함수와 동일.
  • Pattern.flags: regex 매칭 플래그. compile()에 준 플래그, 패턴의 (?...) 인라인 플래그, 유니코드 문자열 패턴이면 UNICODE 같은 암시적 플래그의 조합.
  • Pattern.groups: 패턴의 캡처 그룹 수.
  • Pattern.groupindex: (?P<id>)로 정의된 기호 그룹 이름을 그룹 번호에 매핑한 사전.
  • Pattern.pattern: 패턴 객체가 컴파일된 패턴 문자열.

매치 객체 (Match Objects)

Match 객체는 항상 불리언 값 True를 가져요. match()search()는 매치가 없으면 None을 반환하므로, 간단한 if 문으로 매치 여부를 테스트할 수 있어요:

match = re.search(pattern, string)
if match:
    process(match)

class re.Match

성공적인 매치와 검색이 반환하는 Match 객체예요.

  • Match.expand(template): sub() 메서드처럼 템플릿 문자열 template에 백슬래시 치환을 수행해 얻은 문자열을 반환해요. \n 같은 이스케이프는 적절한 문자로 변환되고, 숫자 역참조(\1, \2)와 이름 역참조(\g<1>, \g<name>)는 해당 그룹의 내용으로 바뀌어요. \g<0>은 전체 매치로 바뀌어요.
  • Match.group([group1, ...]): 매치의 하나 이상 하위 그룹을 반환해요. 인자 하나면 단일 문자열, 여러 인자면 인자당 하나씩의 튜플이에요. 인자가 없으면 group1은 0(전체 매치)이 기본이에요. 그룹 번호가 음수이거나 패턴에 정의된 그룹 수보다 크면 IndexError가 발생해요. 참여하지 않은 그룹은 None이고, 여러 번 매칭된 그룹은 마지막 매치를 반환해요.
>>> m = re.match(r"(\w+) (\w+)", "Isaac Newton, physicist")
>>> m.group(0)       # The entire match
'Isaac Newton'
>>> m.group(1)       # The first parenthesized subgroup.
'Isaac'
>>> m.group(1, 2)    # Multiple arguments give us a tuple.
('Isaac', 'Newton')
  • Match.__getitem__(g): m.group(g)와 동일해요. m[0], m[1]처럼 쓸 수 있게 해요. 버전 3.6에서 추가.
  • Match.groups(default=None): 매치의 모든 하위 그룹을 담은 튜플을 반환해요.
  • Match.groupdict(default=None): 매치의 모든 이름 있는 하위 그룹을 하위 그룹 이름 키로 담은 사전을 반환해요.
  • Match.start([group]), Match.end([group]): group이 매칭한 부분 문자열의 시작과 끝 인덱스를 반환해요. group은 기본 0(전체 매치)이에요. 그룹이 매치에 기여하지 않았으면 -1을 반환해요. m.string[m.start(g):m.end(g)]가 그룹이 매칭한 부분 문자열이에요.
  • Match.span([group]): (m.start(group), m.end(group)) 2-튜플을 반환해요. 그룹이 매치에 기여하지 않았으면 (-1, -1).
  • Match.pos, Match.endpos: regex 객체의 search()match()에 넘긴 pos, endpos 값.
  • Match.lastindex: 마지막으로 매칭된 캡처 그룹의 정수 인덱스, 그룹이 전혀 매칭되지 않았으면 None.
  • Match.lastgroup: 마지막으로 매칭된 캡처 그룹의 이름.
  • Match.re: 이 매치 인스턴스를 만든 정규 표현식 객체.
  • Match.string: match()search()에 넘긴 문자열.

정규 표현식 예시 (Regular Expression Examples)

search() vs. match()의 차이: search()는 문자열 어디서든 매치를 찾지만 match()는 문자열 시작에서만 매치합니다. match()pattern.search(string, pos)처럼 컴파일된 패턴의 search()pos를 주는 것으로 근사할 수 있어요.

findall() 예시는 위 함수 부분을, group() 등 매치 객체 예시는 위 매치 객체 부분을 참고하세요. 포커 핸드 검증, scanf() 시뮬레이션 같은 더 많은 예시는 원문 "Regular Expression Examples" 섹션을 참고해요.

더 알아보기

  • 정규 표현식 문법과 개념에 대한 더 부드러운 소개는 regex HOWTO(Regular expression HOWTO)를 참고하세요.
  • 표준 라이브러리 re 모듈과 API 호환이면서 추가 기능과 더 철저한 유니코드 지원을 제공하는 서드파티 regex 모듈.