re — 정규 표현식 작업¶
소스 코드: Lib/re/
이 모듈은 Perl에 있는 것과 유사한 정규식 일치 연산을 제공합니다.
검색할 패턴과 문자열은 유니코드 문자열(str)과 8비트 문자열(bytes) 모두 가능합니다. 그러나 유니코드 문자열과 8비트 문자열을 혼합해서 사용할 수 없습니다. 즉, 유니코드 문자열을 바이트 패턴으로 매칭하거나 그 반대의 경우도 불가능합니다. 마찬가지로 치환을 요청할 때 대체 문자열은 패턴 및 검색 문자열과 동일한 타입이어야 합니다.
정규식은 백슬래시 문자('\')를 사용하여 특수 형식을 나타내거나, 특수 문자가 특별한 의미를 갖지 않고 사용되도록 합니다. 이는 파이썬이 문자열 리터럴에서 동일한 목적을 위해 같은 문자를 사용하는 방식과 충돌합니다. 예를 들어, 실제 백슬래시와 일치시키려면 패턴 문자열을 '\\\\' 로 작성해야 할 수도 있습니다. 정규식은 \\ 여야 하며, 일반 파이썬 문자열 리터럴 내부에서 각 백슬래시는 \\ 로 표현되어야 하기 때문입니다. 또한, 파이썬의 문자열 리터럴 내 백슬래시 사용 시 잘못된 이스케이프 시퀀스는 현재 SyntaxWarning 을 발생시키며, 향후에는 SyntaxError 가 될 예정입니다. 이는 정규식에 대해서는 유효한 이스케이프 시퀀스인 경우에도 발생합니다.
해결책은 정규식 패턴에 파이썬의 날 문자열(raw string) 표기법을 사용하는 것입니다; 역 슬래시는 'r' 접두어가 붙은 문자열 리터럴에서 특별한 방법으로 처리되지 않습니다. 따라서 r"\n"은 '\'와 'n'을 포함하는 두 글자 문자열이고, "\n"은 개행을 포함하는 한 글자 문자열입니다. 일반적으로 패턴은, 이 날 문자열 표기법을 사용하여 파이썬 코드로 표현됩니다.
대부분 정규식 연산은 모듈 수준 함수와 컴파일된 정규식의 메서드로 사용할 수 있다는 점에 유의해야 합니다. 함수는 정규식 객체를 먼저 컴파일할 필요가 없도록 하는 바로 가기이지만, 일부 미세 조정 매개 변수가 빠져있습니다.
더 보기
표준 라이브러리인 re 모듈과 호환되는 API를 제공하면서도 추가 기능과 더욱 철저한 유니코드 지원을 제공하는 서드파티 regex 모듈입니다.
정규식 문법¶
정규식(또는 RE)은 일치하는 문자열 집합을 지정합니다; 이 모듈의 함수는 특정 문자열이 주어진 정규식과 일치하는지 확인할 수 있도록 합니다 (또는 주어진 정규식이 특정 문자열과 일치하는지, 결국 같은 결과를 줍니다).
정규식을 이어붙여서 새로운 정규식을 만들 수 있습니다; A와 B가 모두 정규식이면 AB도 정규식입니다. 일반적으로 문자열 p가 A와 일치하고 다른 문자열 q가 B와 일치하면 문자열 pq가 AB와 일치합니다. 이것은 A나 B가 우선순위가 낮은 연산, A와 B 사이의 경계 조건 또는 숫자 그룹 참조를 포함하지 않는 한 성립합니다. 따라서, 복잡한 정규식은 여기에 설명된 것과 같은 더 단순한 기본 정규식으로 쉽게 구성할 수 있습니다. 정규식의 이론과 구현에 관한 자세한 내용은 Friedl 책 [Frie09], 또는 컴파일러 작성에 관한 거의 모든 교과서를 참조하십시오.
정규식의 형식에 대한 간단한 설명이 이어집니다. 더 자세한 정보와 더 친절한 소개는 정규식 HOWTO를 참조하십시오.
정규식은 특수 문자와 일반 문자를 모두 포함 할 수 있습니다. 'A', 'a' 또는 '0'과 같은 대부분의 일반 문자는 가장 단순한 정규식입니다; 그들은 단순히 자신과 일치합니다. 일반 문자를 이어 붙일 수 있어서, last는 'last' 문자열과 일치합니다. (이 절의 나머지 부분에서는, RE를 (보통 따옴표 없이) 이런 특별한 스타일로, 일치할 문자열은 '작은따옴표 안에' 씁니다.)
'|'나 '('와 같은 일부 문자는 특수합니다. 특수 문자는 일반 문자의 클래스를 나타내거나, 그 주변의 정규식이 해석되는 방식에 영향을 줍니다.
Repetition operators or quantifiers (*, +, ?, {m,n}, etc) cannot be
directly nested. This avoids ambiguity with the non-greedy modifier suffix
?, and with other modifiers in other implementations. To apply a second
repetition to an inner repetition, parentheses may be used. For example,
the expression (?:a{6})* matches any multiple of six 'a' characters.
특수 문자는 다음과 같습니다:
.(닷트(.)) 기본 모드에서 이 문자는 개행 문자를 제외한 모든 문자와 일치합니다.
DOTALL플래그가 지정된 경우, 개행 문자를 포함한 모든 문자와 일치합니다.(?s:.)는 플래그와 관계없이 모든 문자와 일치합니다.
^(캐럿.) 문자열의 시작과 일치하고,
MULTILINE모드에서는 각 개행 직후에도 일치합니다.
$문자열의 끝이나 문자열 끝의 개행 문자 바로 직전과 일치하고,
MULTILINE모드에서는 개행 문자 앞에서도 일치합니다.foo는 ‘foo’와 ‘foobar’를 모두 일치시키는 반면, 정규식foo$는 ‘foo’ 만 일치합니다. 흥미롭게도,'foo1\nfoo2\n'에서foo.$를 검색하면 ‘foo2’ 는 정상적으로 일치되지만, ‘foo1’은MULTILINE모드에서 검색됩니다;'foo\n'에서 단일$를 검색하면 두 개의 (빈) 일치가 발견됩니다: 하나는 개행 직전에, 다른 하나는 문자열 끝에.
*결과 RE가 선행 RE의 가능한 한 많은 0회 이상의 반복과 일치하도록 합니다.
ab*는 ‘a’, ‘ab’ 또는 ‘a’ 다음에 임의의 수의 ‘b’가 오는 것과 일치합니다.
+결과 RE가 선행 RE의 1회 이상의 반복과 일치하도록 합니다.
ab+는 ‘a’ 다음에 하나 이상의 ‘b’가 오는 것과 일치합니다; 단지 ‘a’와는 일치하지 않습니다.
?결과 RE가 선행 RE의 0 또는 1 반복과 일치하도록 합니다.
ab?는 ‘a’나 ‘ab’와 일치합니다.
*?,+?,??`'*',`'+','?'한정자는 모두 탐욕적(greedy) 이며, 가능한 한 많은 텍스트를 일치시킵니다. 때때로 이러한 동작은 원치 않을 수 있습니다. 예를 들어 정규식<.*>를'<a> b <c>'와 대조하면, 단지'<a>'가 아니라 전체 문자열이 일치하게 됩니다. 한정자 뒤에?를 추가하면 비탐욕적(non-greedy) 또는 최소(minimal) 방식으로 매칭을 수행하여 가능한 적은 수의 문자와만 일치시킵니다. 정규식<.*?>를 사용하면'<a>'만 일치하게 됩니다.
*+,++,?+`'*','+','?'한정자와 마찬가지로,'+'가 추가된 경우도 가능한 한 많이 일치시킵니다. 그러나 진정한 탐욕적 한정자와 달리, 이들은 뒤따르는 표현식이 일치하지 않을 때 역추적(back-tracking)을 허용하지 않습니다. 이를 소유적(possessive) 한정자라고 합니다. 예를 들어,a*a는'aaaa'와 일치합니다.a*가 4개의'a'모두를 일치시켰으나 마지막'a'를 만났을 때 표현식이 역추적되어 결국a*가 총 3개의'a'를 일치시키고, 네 번째'a'는 마지막'a'에 의해 일치하게 됩니다. 그러나'aaaa'를 매칭하기 위해a*+a를 사용하면,a*+가 4개의'a'모두를 일치시켰을 때 마지막'a'가 더 이상 매칭할 문자를 찾지 못하면 표현식이 역추적될 수 없으므로 매칭에 실패하게 됩니다.x*+,x++및x?+는 각각(?>x*),(?>x+)및(?>x?)와 동일합니다.Added in version 3.11.
{m}선행 RE의 정확히 m 복사가 일치하도록 지정합니다; 적은 횟수의 일치는 전체 RE가 일치하지 않게 됩니다. 예를 들어,
a{6}는 정확히 6개의'a'문자와 일치하지만, 5개의 문자와는 일치하지 않습니다.{m,n}결과 RE를 선행 RE의 m에서 n 사이의 최대한 많은 반복과 일치하도록 합니다. 예를 들어,
a{3,5}는 3에서 5개의'a'문자와 일치합니다. m을 생략하면 하한값 0이 지정되고, n을 생략하면 무한한 상한이 지정됩니다. 예를 들어,a{4,}b는'aaaab'나 1000개의'a'문자와'b'가 일치하지만,'aaab'는 일치하지 않습니다. 콤마는 생략할 수 없습니다, 그렇지 않으면 한정자가 앞에서 설명한 형식과 혼동될 수 있습니다.{m,n}?결과 정규식을 선행 정규식의 m 에서 n 번 반복되는 범위 내에서 가능한 한 적은 횟수를 일치시키도록 합니다. 이는 이전 한정자의 비탐욕적 버전입니다. 예를 들어, 6개의 문자가 있는 문자열
'aaaaaa'에서a{3,5}는 5개의'a'를 일치시키지만,a{3,5}?는 3개만 일치시킵니다.{m,n}+결과 정규식을 선행 정규식의 m 에서 n 번 반복되는 범위 내에서 역추적 지점을 생성하지 않으면서 가능한 한 많은 횟수를 일치시키도록 합니다. 이는 위의 한정자의 소유적 버전입니다. 예를 들어, 6개의 문자가 있는 문자열
'aaaaaa'에서a{3,5}+aa는 5개의'a'를 시도하여 매칭한 후, 추가로 2개의'a'가 더 필요하지만 가용한 문자가 부족하여 매칭에 실패하는 반면,a{3,5}aa는a{3,5}가 먼저 5개를 점유하고 이후 역추적을 통해 4개만 남기고, 나머지 2개가 패턴 끝의aa와 일치하게 됩니다.x{m,n}+은(?>x{m,n})과 동일합니다.Added in version 3.11.
\특수 문자를 이스케이프 하거나 (
'*','?'등의 문자를 일치시킬 수 있도록 합니다), 특수 시퀀스를 알립니다; 특수 시퀀스는 아래에서 설명합니다.날 문자열을 사용하여 패턴을 표현하지 않는다면, 파이썬이 문자열 리터럴에서 이스케이프 시퀀스로 역 슬래시를 사용한다는 것을 기억하십시오; 이스케이프 시퀀스가 파이썬의 구문 분석기에 의해 인식되지 않으면, 역 슬래시와 후속 문자가 결과 문자열에 포함됩니다. 그러나 파이썬이 결과 시퀀스를 인식한다면 역 슬래시는 두 번 반복되어야 합니다. 이것은 복잡하고 이해하기 어렵기 때문에, 가장 단순한 표현 이외에는 날 문자열을 사용하는 것이 좋습니다.
[]문자 집합을 나타내는 데 사용됩니다. 집합 안에서:
문자는 개별적으로 나열 할 수 있습니다, 예를 들어
[amk]는'a','m'또는'k'와 일치합니다.
문자의 범위는
'-'로 구분된 두 문자를 주고는 것으로 나타낼 수 있습니다, 예를 들어[a-z]는 모든 소문자 ASCII 문자와 일치하고,[0-5][0-9]는00에서59까지의 모든 두 자리 숫자와 일치하며,[0-9A-Fa-f]는 모든 16진수와 일치합니다.-가 이스케이프 처리되거나 (예를 들어[a\-z]) 첫 번째나 마지막 문자로 배치되면 (예를 들어[-a]나[a-]) 리터럴'-'와 일치합니다.백슬래시를 제외한 특수 문자들은 집합 내부에서 특별한 의미를 잃습니다. 예를 들어,
[(+*)]``는 문자 그대로의 ``'(','+','*'또는')'중 어느 하나라도 일치합니다.
백슬래시는 집합 내에서
'-',']','^'및'\\'자체와 같이 특별한 의미를 갖는 문자를 이스케이프하거나,\xa0또는 `` `` 과 같은 단일 문자를 나타내는 특수 시퀀스나\w또는\S(아래 정의됨)와 같은 문자 클래스를 나타냅니다. 참고로\b은 집합 밖에서처럼 단어 경계가 아니라 단일 “백스페이스” 문자를 의미하며,\1과 같은 숫자 이스케이프는 항상 8진수 이스케이프이며 그룹 참조가 아닙니다.\A및\z와 같이 단일 문자와 일치하지 않는 특수 시퀀스는 허용되지 않습니다.
범위 내에 있지 않은 문자는 여집합(complementing)을 만들어 일치할 수 있습니다. 집합의 첫 번째 문자가
'^'이면, 집합에 속하지 않은 모든 문자가 일치합니다. 예를 들어,[^5]는'5'를 제외한 모든 문자와 일치하며,[^^]는'^'를 제외한 모든 문자와 일치합니다.^는 집합의 첫 번째 문자가 아닐 때 특별한 의미가 없습니다.집합 내에서 문자 그대로의
']'``을 일치시키려면 백슬래시를 앞에 붙이거나 집합의 시작 부분에 배치하십시오. 예를 들어, ``[()[\]{}]``와 ``[]()[{}]모두 우괄호뿐만 아니라 좌괄호, 중괄호, 소괄호와 일치합니다.
문자 집합은 대괄호로 쓰인 중첩된 집합을 포함할 수 있으며, 두 개의 집합은 Unicode Technical Standard #18 에서와 같이 집합 연산자로 결합될 수 있습니다.
[A--B](차집합)은 A 에 속하지만 B 에는 속하지 않는 문자를 일치시킵니다. 예를 들어,[a-z--[aeiou]]는 ASCII 소문자 자음과 일치합니다.[A&&B](교집합)은 A 와 B 모두에 속하는 문자를 일치시킵니다. 예를 들어,[\w&&[a-z]]는 ASCII 소문자와 일치합니다.[A||B](합집합)은 A 또는 B 에 속하는 문자를 일치시킵니다. 이는 두 집합의 모든 원소를 하나의 집합에 나열하는 것과 같지만, 중첩된 집합을 결합할 수 있다는 장점이 있습니다.
연산자는 우선순위가 없으며 왼쪽에서 오른쪽으로 적용됩니다. 그룹화하려면
[a-z--[aeiou]]와 같이 연산자 뒤에 중첩된 집합을 피연산자로 작성하십시오. 앞부분의'^'은 전체 결과에 대해 여집합을 취합니다.'['는 집합 연산자 바로 뒤에서만 중첩된 집합의 시작으로 인식되며, 그 외의 장소(문자 집합의 시작 포함)에서는 일반 문자로 간주되므로 기존 패턴의 의미가 유지됩니다. 연산자 바로 뒤에 문자 그대로의'['를 포함하려면'\['로 이스케이프 처리하십시오.
참고
대칭 차집합(
A~~B)은 아직 지원되지 않습니다. 문자 집합 내의 실제'~~'는 여전히FutureWarning을 발생시킵니다.버전 3.7에서 변경: 문자 집합이 미래에 의미가 변할 구조를 포함하고 있다면
FutureWarning이 발생합니다.버전 3.16.0a0 (unreleased)에서 변경: 중첩된 집합과 집합 연산자
--,&&,||에 대한 지원이 추가되었습니다.
|A|B(여기서 A와 B는 임의의 RE일 수 있습니다)는 A나 B와 일치하는 정규식을 만듭니다. 이러한 방식으로 임의의 수의 RE를'|'로 분리 할 수 있습니다. 이것은 그룹(아래를 참조하세요)에서도 사용할 수 있습니다. 대상 문자열이 스캔 될 때'|'로 구분된 RE는 왼쪽에서 오른쪽으로 시도됩니다. 한 패턴이 완전히 일치하면, 해당 분기가 받아들여집니다. 이는 일단 A가 일치하면, B는 전체적으로 더 긴 일치를 생성하더라도 더 검사되지 않는다는 것을 뜻합니다. 즉,'|'연산자는 절대로 탐욕적이지 않습니다. 리터럴'|'와 일치시키려면,\|를 사용하거나,[|]처럼 문자 클래스 안에 넣으십시오.
(...)괄호 안에 있는 정규식과 일치하며, 그룹의 시작과 끝을 나타냅니다; 그룹의 내용은 일치가 수행된 후 조회할 수 있으며, 나중에 문자열에서
\number특수 시퀀스로 일치시킬 수 있습니다 (아래에서 설명됩니다). 리터럴'('나')'를 일치시키려면,\(나\)를 사용하거나, 문자 클래스 안에 넣으십시오:[(],[)].
(?...)이것은 확장 표기법입니다 (그렇지 않으면
'('다음에 오는'?'는 의미가 없습니다).'?'다음의 첫 번째 문자는 확장의 의미와 이후의 문법을 결정합니다. 확장은 대개 새 그룹을 만들지 않습니다; 이 규칙에 대한 유일한 예외는(?P<name>...)입니다. 다음은 현재 지원되는 확장입니다.(?aiLmsux)(집합
'a','i','L','m','s','u','x'중 하나 이상의 문자.) 이 그룹은 빈 문자열과 일치하며, 포함된 문자는 전체 정규식에 대해 다음과 같은 플래그를 설정합니다:re.A(ASCII 전용 매칭)re.I(대소문자 구분 안 함)re.L(로케일 종속)re.M(다중 행)re.S(점(.)이 모든 문자와 일치)re.U(유니코드 매칭)re.X(상세 모드)
(플래그는 모듈 내용 에서 설명합니다.) 이 형식은
re.compile()함수에 *flag* 인자를 전달하는 대신 정규식 자체의 일부로 플래그를 포함하고자 할 때 유용합니다. 플래그는 표현식 문자열의 맨 앞에 위치해야 합니다.버전 3.11에서 변경: 이 구문은 표현식의 시작 부분에서만 사용할 수 있습니다.
(?:...)일반 괄호의 비 포착 버전. 괄호 안의 정규식과 일치하지만, 그룹과 일치하는 부분 문자열은 일치를 수행한 후 조회하거나 나중에 패턴에서 참조할 수 없습니다.
(?aiLmsux-imsx:...)(집합
'a','i','L','m','s','u','x'중 0개 이상의 문자이며, 선택적으로'-'뒤에'i','m','s','x'중 하나 이상의 문자가 올 수 있습니다.) 포함된 문자는 해당 부분의 표현식에 대해 관련 플래그를 설정하거나 해제합니다:re.A(ASCII 전용 매칭)re.I(대소문자 구분 안 함)re.L(로케일 종속)re.M(다중 행)re.S(점(.)이 모든 문자와 일치)re.U(유니코드 매칭)re.X(상세 모드)
(플래그는 모듈 내용 에서 설명합니다.)
인라인 플래그로 사용될 때
'a','L','u'는 상호 배타적이므로 결합하거나'-'뒤에 올 수 없습니다. 대신 인라인 그룹 내에서 이 중 하나가 나타나면 해당 그룹을 감싸는 범위의 매칭 모드를 덮어씌웁니다. 유니코드 패턴(?a:...)는 ASCII 전용 매칭으로,(?u:...)는 유니코드 매칭(기본값)으로 전환합니다. 바이트 패턴(?L:...)는 로케일 종속 매칭으로,(?a:...)는 ASCII 전용 매칭(기본값)으로 전환합니다. 이 덮어쓰기는 해당 인라인 그룹 내에서만 유효하며, 그룹 외부에서는 원래의 매칭 모드가 복원됩니다.Added in version 3.6.
버전 3.7에서 변경: 문자
'a','L'및'u'도 그룹에서 사용할 수 있습니다.(?>...)...을 별개의 정규식인 것처럼 매칭을 시도하고, 성공하면 그 뒤에 이어지는 패턴의 나머지 부분을 계속 매칭합니다. 만약 후속 패턴이 일치하지 않으면 스택은(?>...)앞의 지점으로만 되돌아갈 수 있습니다. 이는 일단 빠져나오면 “원자적 그룹(atomic group)”이라 불리는 해당 표현식이 내부의 모든 스택 지점을 폐기하기 때문입니다. 따라서(?>.*).는 아무것도 일치시키지 못합니다. 먼저.*가 가능한 모든 문자를 매칭하고, 더 이상 매칭할 것이 없으므로 마지막.이 매칭에 실패하게 됩니다. 원자적 그룹 내에 저장된 스택 지점이 없고 그 앞에도 스택 지점이 없기 때문에 전체 표현식이 일치하지 않게 되는 것입니다.Added in version 3.11.
(?P<name>...)일반 괄호와 유사하지만, 그룹에 의해 매칭된 부분 문자열을 기호(symbolic) 그룹 이름 name 을 통해 접근할 수 있습니다. 그룹 이름은 유효한 파이썬 식별자여야 하며,
bytes패턴의 경우 ASCII 범위 내의 바이트만 포함할 수 있습니다. 각 그룹 이름은 정규식 내에서 단 한 번만 정의되어야 합니다. 기호 그룹은 이름이 지정되지 않은 경우와 마찬가지로 번호가 매겨진 그룹이기도 합니다.이름 있는 그룹은 세 가지 문맥에서 참조될 수 있습니다. 패턴이
(?P<quote>['"]).*?(?P=quote)면 (즉, 작은따옴표나 큰따옴표로 인용된 문자열과 일치):그룹 “quote”에 대한 참조 문맥
참조하는 방법
같은 패턴 자체에서
(?P=quote)(보이는 대로)\1
일치 객체 m을 처리할 때
m.group('quote')m.end('quote')(등)
re.sub()의 repl 인자로 전달되는 문자열에서\g<quote>\g<1>\1
버전 3.12에서 변경:
bytes패턴에서 그룹 name 은 ASCII 범위 내의 바이트만 포함할 수 있습니다(b'\x00'-b'\x7f').
(?P=name)이름있는 그룹에 대한 역참조; name이라는 이름의 앞선 그룹과 일치하는 텍스트와 일치합니다.
(?#...)주석; 괄호의 내용은 단순히 무시됩니다.
(?=...)...가 다음과 일치하면 일치하지만, 문자열을 소비하지는 않습니다. 이를 미리 보기 어서션 (lookahead assertion)이라고 합니다. 예를 들어,Isaac (?=Asimov)는'Asimov'가 뒤따를 때만'Isaac '과 일치합니다.
(?!...)...가 다음과 일치하지 않으면 일치합니다. 이것은 부정적인 미리 보기 어서션 (negative lookahead assertion)입니다. 예를 들어,Isaac (?!Asimov)는'Asimov'가 뒤따르지 않을 때 만'Isaac '과 일치합니다.
(?<=...)문자열의 현재 위치 앞에 현재 위치에서 끝나는
...와의 일치가 있으면 일치합니다. 이를 긍정적인 되돌아보기 어서션 (positive lookbehind assertion)이라고 합니다. 되돌아보기가 3문자를 백업하고 포함된 패턴이 일치하는지 확인하기 때문에(?<=abc)def는'abcdef'에서 일치를 찾습니다. 포함된 패턴은 고정 길이의 문자열과 일치해야 합니다, 즉,abc나a|b는 허용되지만,a*와a{3,4}는 허용되지 않습니다. 긍정적인 되돌아보기 어서션으로 시작하는 패턴은 검색되는 문자열의 시작 부분에서 일치하지 않음에 유의하십시오;match()함수보다는search()함수를 사용하기를 원할 것입니다:>>> import re >>> m = re.search('(?<=abc)def', 'abcdef') >>> m.group(0) 'def'
이 예에서는 하이픈 다음의 단어를 찾습니다:
>>> m = re.search(r'(?<=-)\w+', 'spam-egg') >>> m.group(0) 'egg'
버전 3.5에서 변경: 고정 길이의 그룹 참조에 대한 지원이 추가되었습니다.
(?<!...)문자열의 현재 위치 앞에
...와의 일치가 없으면 일치합니다. 이를 부정적인 뒤돌아보기 어서션 (negative lookbehind assertion)이라고 합니다. 긍정적인 뒤돌아보기 어서션과 마찬가지로, 포함된 패턴은 고정 길이의 문자열과 일치해야 합니다. 부정적인 뒤돌아보기 어서션으로 시작하는 패턴은 검색되는 문자열의 시작 부분에서 일치 할 수 있습니다.
(?(id/name)yes-pattern|no-pattern)주어진 id 또는 name 의 그룹이 존재하면
yes-pattern과 일치를 시도하고, 존재하지 않으면no-pattern과 일치를 시도합니다.no-pattern은 선택 사항이며 생략할 수 있습니다. 예를 들어,(<)?(\w+@\w+(?:\.\w+)+)(?(1)>|$)는 정교하지 못한 이메일 매칭 패턴으로,'<user@host.com>'및'user@host.com'과 일치하지만,'<user@host.com'또는'user@host.com>'와 전체가 일치하지는 않습니다. (re.search()는 전자 사례에서'user@host.com'만 찾아냅니다.)버전 3.12에서 변경: 그룹 id 는 ASCII 숫자만 포함할 수 있습니다.
bytes패턴에서 그룹 name 은 ASCII 범위(b'\x00'-b'\x7f') 내의 바이트만 포함할 수 있습니다.
특수 시퀀스는 '\'와 아래 목록의 문자로 구성됩니다. 일반 문자가 ASCII 숫자나 ASCII 글자가 아니면, 결과 RE는 두 번째 문자와 일치합니다. 예를 들어, \$는 문자 '$'와 일치합니다.
\number같은 번호의 그룹 내용과 일치합니다. 그룹은 1부터 번호가 매겨집니다. 예를 들어,
(.+) \1은'the the'나'55 55'와 일치하지만,'thethe'와는 일치하지 않습니다 (그룹 뒤의 공백에 유의하십시오). 이 특수 시퀀스는 첫 99개 그룹 중 하나와 일치하는 데에만 사용될 수 있습니다. number의 첫 자릿수가 0이거나, number가 3 자릿수면, 그룹 일치로 해석되지 않고, 8진수 값 number를 갖는 문자로 해석됩니다. 문자 클래스의'['와']'안에서는, 모든 숫자 이스케이프가 문자로 처리됩니다.
\A문자열의 시작 부분에서만 일치합니다.
\b빈 문자열과 일치하지만, 단어의 시작이나 끝에서만 일치합니다. 단어는 단어 문자의 시퀀스로 정의됩니다. 공식적으로
\b는\w와\W문자 사이(또는 그 반대), 또는\w와 문자열의 시작 또는 끝 사이를 경계로 정의됩니다. 이는r'\bat\b'가'at','at.','(at)'및'as at ay'와는 일치하지만'attempt'나'atlas'와는 일치하지 않음을 의미합니다.Unicode (str) 패턴에서 기본 단어 문자는 Unicode 영숫자와 밑줄이며, 이는
ASCII플래그를 사용하여 변경할 수 있습니다.LOCALE플래그를 사용하면 단어 경계가 현재 로케일에 따라 결정됩니다.참고
문자 범위 내에서
\b는 파이썬의 문자열 리터럴과의 호환성을 위해 백스페이스 문자를 나타냅니다.
\B빈 문자열과 일치하지만, 단어의 시작이나 끝에 있지 않은 경우에만 일치합니다. 이는
r'at\B'가'athens','atom','attorney'와는 일치하지만'at','at.'또는'at!'와는 일치하지 않음을 의미합니다.\B는\b의 반대이며, Unicode (str) 패턴에서 단어 문자는 영숫자 또는 밑줄입니다. 다만 이는ASCII플래그를 사용하여 변경할 수 있습니다.LOCALE플래그가 사용되는 경우 단어 경계는 현재 로케일에 따라 결정됩니다.버전 3.14에서 변경:
\B이(가) 이제 빈 입력 문자열과 일치합니다.
\d
\D십진 숫자가 아닌 모든 문자와 일치합니다. 이는
\d의 반대입니다.ASCII플래그를 사용하면[^0-9]과 일치합니다.
\s- 유니코드 (str) 패턴일 때:
Unicode 공백 문자(
str.isspace()에 정의된 대로)와 일치합니다. 여기에는[ \t\n\r\f\v]뿐만 아니라, 여러 언어의 타이포그래피 규칙에 의해 요구되는 줄 바꿈 없는 공백과 같은 많은 다른 문자들이 포함됩니다.ASCII플래그를 사용하면[ \t\n\r\f\v]과 일치합니다.- 8비트 (bytes) 패턴일 때:
ASCII 문자 집합에서 공백으로 간주하는 문자와 일치합니다; 이것은
[ \t\n\r\f\v]와 동등합니다.
\S공백 문자가 아닌 모든 문자와 일치합니다. 이는
\s의 반대입니다.ASCII플래그를 사용하면[^ \t\n\r\f\v]과 일치합니다.
\w- 유니코드 (str) 패턴일 때:
Unicode 단어 문자와 일치하며, 여기에는 모든 Unicode 영숫자 문자(
str.isalnum()에 정의된 대로)와 밑줄(_)이 포함됩니다.ASCII플래그를 사용하면[a-zA-Z0-9_]과 일치합니다.- 8비트 (bytes) 패턴일 때:
ASCII 문자 집합에서 영숫자로 간주되는 문자와 일치하며, 이는
[a-zA-Z0-9_]와 동일합니다.LOCALE플래그가 사용되면 현재 로케일에서 영숫자로 간주하는 문자와 밑줄과 일치합니다.
\W단어 문자가 아닌 모든 문자와 일치합니다. 이는
\w의 반대입니다. 기본적으로str.isalnum()이False를 반환하는 밑줄(_)이 아닌 문자들과 일치합니다.ASCII플래그를 사용하면[^a-zA-Z0-9_]과 일치합니다.LOCALE플래그가 사용되는 경우, 현재 로케일에서 영숫자가 아니며 밑줄도 아닌 문자와 일치합니다.
\p{property=value},\p{value}Matches any character with the given Unicode property (see Unicode Technical Standard #18, requirement RL1.2 “Properties”). Property and value names are matched loosely: case, whitespace,
'-'and'_'are ignored. The following properties are supported:General_Category속성(짧은 이름gc)은\p{Lu},\p{gc=Lu}로 표기하거나, 한 글자 그룹의 경우\p{L}로 표기합니다. 지원되는 값은 그룹L,N,Z및C이고, 세부 값으로는Lu,Lt,Lm,Nd,Nl,No,Zs,Zl,Zp,Cc,Cf,Cs,Co및Cn이 있습니다.이진(binary) 속성인
XID_Start,XID_Continue,Alphabetic,Lowercase,Uppercase,Numeric,Printable,Cased및Case_Ignorable이 있습니다. 이진 속성은\p{name=yes}또는\p{name=no}로도 표기할 수 있습니다.POSIX 호환성 클래스인
alpha,alnum,blank,cntrl,digit,graph,lower,print,space,upper,word및xdigit이 있습니다.ASCII,Any,Assigned,Noncharacter_Code_Point,Join_Control,Regional_Indicator,ASCII_Hex_Digit,Hex_Digit,Pattern_Syntax및Pattern_White_Space속성이 있습니다.
지원되는 속성이
unicodedata접근자 또는str메서드에 대응하는 경우, 해당 속성이 매칭하는 문자 세트는 그들이 보고하는 것과 정확히 일치합니다. 일관성을 위해space는\s와 마찬가지로str.isspace()를 따르며,xdigit은 ASCII 16진수만 매칭합니다.이것은 유니코드(str) 패턴에서만 인식됩니다. 바이트(bytes) 패턴에서는 오류가 발생합니다.
Added in version 3.16.0a0 (unreleased).
\P{...}주어진 유니코드 속성을 가지지 않는 모든 문자를 매칭합니다. 이는
\p의 반대입니다.Added in version 3.16.0a0 (unreleased).
\z문자열 끝에만 일치합니다.
Added in version 3.14.
\Z\z와 동일합니다. 이전 파이썬 버전과의 호환성을 위해 제공됩니다.
Python 문자열 리터럴이 지원하는 대부분의 escape sequences 가 정규 표현식 파서에서도 수용됩니다:
\a \b \f \n
\N \r \t \u
\U \v \x \\
(\b는 단어 경계를 나타내는 데 사용되며, 문자 클래스 내에서만 “백스페이스”를 의미함에 유의하십시오.)
'\u', '\U' 및 '\N' 이스케이프 시퀀스는 Unicode (str) 패턴에서만 인식됩니다. 바이트 패턴에서는 오류로 처리됩니다. 알 수 없는 ASCII 문자 이스케이프는 향후 사용을 위해 예약되어 있으며 오류로 처리됩니다.
8진수 이스케이프는 제한된 형식으로 포함됩니다. 첫 번째 숫자가 0이거나, 3개의 8진수가 있으면, 8진수 이스케이프로 간주합니다. 그렇지 않으면, 그룹 참조입니다. 문자열 리터럴과 마찬가지로, 8진수 이스케이프 길이는 항상 최대 3자리입니다.
버전 3.3에서 변경: '\u'와 '\U' 이스케이프 시퀀스가 추가되었습니다.
버전 3.6에서 변경: '\'와 ASCII 글자로 구성된 알 수 없는 이스케이프는 이제 에러입니다.
버전 3.8에서 변경: '\N\{{name\}}'` 이스케이프 시퀀스가 추가되었습니다. 문자열 리터럴과 마찬가지로, 이는 명명된 Unicode 문자로 확장됩니다(예: ``'\N{EM DASH}').
모듈 내용¶
모듈은 몇 가지 함수, 상수 및 예외를 정의합니다. 함수 중 일부는 컴파일된 정규식의 모든 기능을 갖춘 메서드의 단순화된 버전입니다. 대부분의 사소하지 않은 응용 프로그램은 항상 컴파일된 형식을 사용합니다.
Flags¶
버전 3.6에서 변경: 플래그 상수는 이제 enum.IntFlag의 서브 클래스인 RegexFlag의 인스턴스입니다.
- class re.RegexFlag¶
아래에 나열된 정규 표현식 옵션을 포함하는
enum.IntFlag클래스입니다.Added in version 3.11: - added to
__all__
- re.A¶
- re.ASCII¶
\w,\W,\b,\B,\d,\D,\s및\S가 전체 Unicode 일치 대신 ASCII 전용 일치를 수행하도록 만듭니다. 이는 Unicode (str) 패턴에서만 의미가 있으며, 바이트 패턴에서는 무시됩니다.인라인 플래그
(?a)에 해당합니다.
- re.DEBUG¶
컴파일된 표현식에 대한 디버그 정보를 표시합니다.
대응하는 인라인 플래그가 없습니다.
- re.I¶
- re.IGNORECASE¶
대소 문자를 구분하지 않는 일치를 수행합니다.
[A-Z]와 같은 표현은 소문자와도 일치하게 됩니다.ASCII플래그를 사용하여 비 ASCII 일치를 비활성화하지 않는 한, 전체 Unicode 일치(예:ü가Ü와 일치)도 작동합니다.LOCALE플래그를 함께 사용하지 않는다면 현재 로케일은 이 플래그의 효과를 변경하지 않습니다.인라인 플래그
(?i)에 해당합니다.Unicode 패턴
[a-z]또는[A-Z]를IGNORECASE플래그와 함께 사용할 경우, 이들은 52개의 ASCII 문자와 추가로 4개의 비 ASCII 문자인 ‘İ’ (U+0130), ‘ı’ (U+0131), ‘ſ’ (U+017F), 그리고 ‘K’ (U+212A)와 일치한다는 점에 유의하십시오.ASCII플래그를 사용하면 ‘a’부터 ‘z’까지, 그리고 ‘A’부터 ‘Z’까지의 문자만 일치합니다.
- re.L¶
- re.LOCALE¶
\w,\W,\b,\B및 대소 문자를 구분하지 않는 일치를 유니코드 데이터베이스 대신 현재 로케일에 의존하게 만듭니다. 이 플래그는 바이트 패턴에서만 사용할 수 있습니다.인라인 플래그
(?L)에 해당합니다.경고
이 플래그는 권장되지 않습니다. 대신 Unicode 일치를 고려하십시오. 로케일 메커니즘은 한 번에 하나의 “문화”만 처리하며 8비트 로케일에서만 작동하므로 매우 신뢰할 수 없습니다. Unicode (str) 패턴의 경우 기본적으로 Unicode 일치가 활성화되며, 이는 다양한 로케일과 언어를 처리할 수 있습니다.
버전 3.7에서 변경:
LOCALE플래그가 포함된 컴파일된 정규 표현식 객체는 더 이상 컴파일 시점에 로케일에 의존하지 않습니다. 일치 시점의 로케일만이 일치 결과에 영향을 미칩니다.
- re.M¶
- re.MULTILINE¶
지정될 경우, 패턴 문자
'^'은 문자열의 시작과 각 줄의 시작(각 줄 바꿈 직후)에서 일치하며; 패턴 문자'$'는 문자열의 끝과 각 줄의 끝(각 줄 바꿈 직전)에서 일치합니다. 기본적으로'^'는 문자열의 시작에서만 일치하고,'$'는 문자열의 끝이며 문자열 끝에 줄 바꿈이 있는 경우 그 바로 앞에서만 일치합니다.인라인 플래그
(?m)에 해당합니다.
- re.NOFLAG¶
어떤 플래그도 적용되지 않음을 나타내며, 값은
0입니다. 이 플래그는 함수 키워드 인수의 기본값이나 다른 플래그와 조건부로 OR 연산될 기초값으로 사용될 수 있습니다. 기본값으로 사용하는 예시:def myfunc(pattern, text, flag=re.NOFLAG): return re.search(pattern, text, flag)
Added in version 3.11.
- re.S¶
- re.DOTALL¶
.특수 문자가 줄 바꿈을 포함하여 모든 문자와 일치하게 만듭니다. 이 플래그가 없으면.는 줄 바꿈을 제외한 모든 것과 일치합니다.인라인 플래그
(?s)에 해당합니다.
- re.U¶
- re.UNICODE¶
Python 3에서는 str 패턴에 대해 기본적으로 유니코드 문자가 일치합니다. 따라서 이 플래그는 아무런 효과가 없으며, 하위 호환성을 위해 유지됩니다.
See
ASCIIto restrict matching to ASCII characters instead.
- re.X¶
- re.VERBOSE¶
이 플래그는 패턴의 논리적 섹션을 시각적으로 분리하고 주석을 추가할 수 있게 하여, 정규 표현식을 더 깔끔하고 읽기 쉽게 작성할 수 있도록 해줍니다. 패턴 내의 공백은 문자 클래스 내에 있거나 이스케이프되지 않은 백슬래시 뒤에 오지 않는 한 무시됩니다. 예를 들어,
(? :나* ?는 허용되지 않습니다. 줄에 문자 클래스에 속하지 않고 이스케이프되지 않은 백슬래시 뒤에 오지 않는#이 포함된 경우, 해당#부터 줄 끝까지의 모든 문자가 무시됩니다.이것은 십진수와 일치하는 다음 두 정규식 객체는 기능적으로 같음을 뜻합니다:
a = re.compile(r"""\d + # 정수 부분 \. # 소수점 \d * # 소수 자릿수 """, re.X) b = re.compile(r"\d+\.\d*")
인라인 플래그
(?x)에 해당합니다.
함수¶
- re.compile(pattern, flags=0)¶
정규 표현식 패턴을 정규식 객체 로 컴파일합니다. 이 객체는 아래 설명된
prefixmatch(),search()및 기타 메서드를 사용하여 일치 여부를 확인하는 데 사용될 수 있습니다.표현식의 동작은 flags 값을 지정하여 수정할 수 있습니다. 값은 flags 변수 중 어느 것이든 될 수 있으며, 비트 논리합(
|연산자)을 사용하여 결합할 수 있습니다.시퀀스
prog = re.compile(pattern) result = prog.search(string)
는 다음과 동등합니다
result = re.search(pattern, string)
하지만 정규식이 단일 프로그램에서 여러 번 사용될 때,
re.compile()을 사용하고 결과 정규식 객체를 저장하여 재사용하는 것이 더 효율적입니다.참고
re.compile()과 모듈 수준 일치 함수에 전달된 가장 최근 패턴의 컴파일된 버전이 캐시 되므로, 한 번에 몇 가지 정규식만 사용하는 프로그램은 정규식 컴파일에 대해 신경 쓸 필요가 없습니다.
- re.search(pattern, string, flags=0)¶
string 을 스캔하여 정규 표현식 pattern 이 일치하는 첫 번째 위치를 찾아 해당
Match객체를 반환합니다. 문자열 내에서 패턴과 일치하는 위치가 없으면None을 반환합니다. 이는 문자열의 특정 지점에서 길이가 0인 일치 항목을 찾는 것과는 다릅니다.표현식의 동작은 flags 값을 지정하여 수정할 수 있습니다. 값은 flags 변수 중 어느 것이든 될 수 있으며, 비트 논리합(
|연산자)을 사용하여 결합할 수 있습니다.
- re.prefixmatch(pattern, string, flags=0)¶
string 의 시작 부분에서 0개 이상의 문자가 정규 표현식 pattern 과 일치하면 해당
Match를 반환합니다. 문자열이 패턴과 일치하지 않으면None을 반환합니다. 이는 길이 0인 일치와는 다르다는 점에 유의하십시오.참고
MULTILINE모드에서도 이 기능은 각 줄의 시작이 아닌 문자열 전체의 시작 부분에서만 일치합니다.string의 모든 위치에서 일치를 찾으려면, 대신
search()를 사용하십시오 (search() 대 prefixmatch()도 참조하십시오).표현식의 동작은 flags 값을 지정하여 수정할 수 있습니다. 값은 flags 변수 중 어느 것이든 될 수 있으며, 비트 논리합(
|연산자)을 사용하여 결합할 수 있습니다.이 함수는 현재 두 개의 이름을 가지고 있으며, 오랫동안
match()로 알려져 왔습니다. 이전 Python 버전과의 호환성을 유지해야 하는 경우 해당 이름을 사용하십시오.Added in version 3.15.
- re.match(pattern, string, flags=0)¶
버전 3.15부터 약하게 폐지 <Soft deprecated>:
match()는 보다 명확하게 설명되는 대체 이름인prefixmatch()를 위해 soft deprecated 되었습니다. 의도를 더 잘 표현하기 위해 이 이름을 사용하십시오. 다른 언어와 정규 표현식 구현에서 표준적으로 match 라는 용어는 Python이 항상search()로 불러온 동작을 지칭하는 데 사용됩니다. 자세한 내용은 prefixmatch() 대 match() 를 참조하십시오.
- re.fullmatch(pattern, string, flags=0)¶
string 전체가 정규 표현식 pattern 과 일치하면 해당
Match를 반환합니다. 문자열이 패턴과 일치하지 않으면None을 반환합니다. 이는 길이 0인 일치와는 다르다는 점에 유의하십시오.표현식의 동작은 flags 값을 지정하여 수정할 수 있습니다. 값은 flags 변수 중 어느 것이든 될 수 있으며, 비트 논리합(
|연산자)을 사용하여 결합할 수 있습니다.Added in version 3.4.
- re.split(pattern, string, maxsplit=0, flags=0)¶
string을 pattern으로 나눕니다. 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']
구분자에 포착하는 그룹이 있고 문자열 시작 부분에서 일치하면, 결과는 빈 문자열로 시작됩니다. 문자열의 끝에 대해서도 마찬가지입니다:
>>> re.split(r'(\W+)', '...words, words...') ['', '...', 'words', ', ', 'words', '...', '']
그런 식으로, 구분자 구성 요소는 항상 결과 리스트 내의 같은 상대 인덱스에서 발견됩니다.
연속된 빈 일치는 불가능하지만, 빈 일치가 비어 있지 않은 일치 직후에 발생할 수 있습니다.
>>> re.split(r'\b', 'Words, words, words.') ['', 'Words', ', ', 'words', ', ', 'words', '.'] >>> re.split(r'\W*', '...words...') ['', '', 'w', 'o', 'r', 'd', 's', '', ''] >>> re.split(r'(\W*)', '...words...') ['', '...', '', '', 'w', '', 'o', '', 'r', '', 'd', '', 's', '...', '', '', '']
표현식의 동작은 flags 값을 지정하여 수정할 수 있습니다. 값은 flags 변수 중 어느 것이든 될 수 있으며, 비트 논리합(
|연산자)을 사용하여 결합할 수 있습니다.버전 3.1에서 변경: 선택적 flags 인자를 추가했습니다.
버전 3.7에서 변경: 빈 문자열과 일치 할 수 있는 패턴으로 분할하는 지원을 추가했습니다.
버전 3.13부터 폐지됨: maxsplit 과 flags 를 위치 인자로 전달하는 방식은 폐지되었습니다. 향후 Python 버전에서는 이들은 키워드 전용 매개 변수 가 됩니다.
- 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')]
표현식의 동작은 flags 값을 지정하여 수정할 수 있습니다. 값은 flags 변수 중 어느 것이든 될 수 있으며, 비트 논리합(
|연산자)을 사용하여 결합할 수 있습니다.버전 3.7에서 변경: 비어 있지 않은 일치는 이제 이전의 비어 있는 일치 직후에 시작할 수 있습니다.
- re.finditer(pattern, string, flags=0)¶
Return an iterator yielding
Matchobjects over all non-overlapping matches for the RE pattern in string. The string is scanned left-to-right, and matches are returned in the order found. Empty matches are included in the result.표현식의 동작은 flags 값을 지정하여 수정할 수 있습니다. 값은 flags 변수 중 어느 것이든 될 수 있으며, 비트 논리합(
|연산자)을 사용하여 결합할 수 있습니다.버전 3.7에서 변경: 비어 있지 않은 일치는 이제 이전의 비어 있는 일치 직후에 시작할 수 있습니다.
- re.sub(pattern, repl, string, count=0, flags=0)¶
string에서 겹치지 않는 pattern의 가장 왼쪽 일치를 repl로 치환하여 얻은 문자열을 반환합니다. 패턴을 찾지 못하면, string이 변경되지 않고 반환됩니다. repl은 문자열이나 함수가 될 수 있습니다; 문자열이면 모든 역 슬래시 이스케이프가 처리됩니다. 즉,
\n은 단일 개행 문자로 변환되고,\r는 캐리지 리턴으로 변환되고, 등등. 알 수 없는 ASCII 글자 이스케이프는 나중에 사용하기 위해 예약되어 있으며 에러로 처리됩니다.\&와 같은 다른 알려지지 않은 이스케이프는 그대로 있습니다.\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'
패턴은 문자열 또는
Pattern일 수 있습니다.선택적 인자 count 는 치환될 패턴 일치의 최대 수이며, count 은 음수가 아닌 정수여야 합니다. 생략되거나 0인 경우 모든 일치가 치환됩니다.
연속된 빈 일치는 불가능하지만, 빈 일치가 비어 있지 않은 일치 직후에 발생할 수 있습니다. 결과적으로
sub('x*', '-', 'abxd')는'-a-b-d-'대신'-a-b--d-'를 반환합니다.문자열형 repl 인자에서, 위에 설명된 문자 이스케이프와 역참조 외에,
\g<name>는(?P<name>...)문법으로 정의한name이라는 그룹에 일치하는 부분 문자열을 사용합니다.\g<number>는 해당 그룹 번호를 사용합니다; 따라서\g<2>는\2와 동등하지만,\g<2>0와 같은 치환에서 모호하지 않습니다.\20은 그룹 2에 대한 참조에 리터럴 문자'0'이 뒤에 오는 것이 아니라, 그룹 20에 대한 참조로 해석됩니다. 역참조\g<0>은 RE와 일치하는 전체 부분 문자열을 치환합니다.표현식의 동작은 flags 값을 지정하여 수정할 수 있습니다. 값은 flags 변수 중 어느 것이든 될 수 있으며, 비트 논리합(
|연산자)을 사용하여 결합할 수 있습니다.버전 3.1에서 변경: 선택적 flags 인자를 추가했습니다.
버전 3.5에서 변경: 일치하지 않는 그룹은 빈 문자열로 치환됩니다.
버전 3.6에서 변경: pattern의
'\'와 ASCII 글자(letter)로 구성된 알 수 없는 이스케이프는 이제 에러입니다.버전 3.7에서 변경: repl 에서
'\'와 ASCII 문자로 구성된 알 수 없는 이스케이프는 이제 오류로 처리됩니다. 빈 일치는 비어 있지 않은 일치 직후에 발생할 수 있습니다.버전 3.12에서 변경: 그룹 id 는 ASCII 숫자만 포함할 수 있습니다.
bytes치환 문자열의 경우, 그룹 name 은 ASCII 범위 내의 바이트(b'\x00'-b'\x7f')만 포함할 수 있습니다.버전 3.13부터 폐지됨: count 과 flags 를 위치 인자로 전달하는 방식은 폐지되었습니다. 향후 Python 버전에서는 이들이 키워드 전용 매개 변수 가 됩니다.
- re.subn(pattern, repl, string, count=0, flags=0)¶
sub()와 같은 연산을 수행하지만, 튜플(new_string, number_of_subs_made)를 반환합니다.표현식의 동작은 flags 값을 지정하여 수정할 수 있습니다. 값은 flags 변수 중 어느 것이든 될 수 있으며, 비트 논리합(
|연산자)을 사용하여 결합할 수 있습니다.
- re.escape(pattern)¶
pattern에서 특수 문자를 이스케이프 처리합니다. 이것은 정규식 메타 문자가 포함되어있을 수 있는 임의의 리터럴 문자열을 일치시키려는 경우에 유용합니다. 예를 들면:
>>> print(re.escape('https://www.python.org')) https://www\.python\.org >>> legal_chars = string.ascii_lowercase + string.digits + "!#$%&'*+-.^_`|~:" >>> print('[%s]+' % re.escape(legal_chars)) [abcdefghijklmnopqrstuvwxyz0123456789!\#\$%\&'\*\+\-\.\^_`\|\~:]+ >>> operators = ['+', '-', '*', '/', '**'] >>> print('|'.join(map(re.escape, sorted(operators, reverse=True)))) /|\-|\+|\*\*|\*
이 함수는
sub()와subn()의 치환 문자열에 사용하면 안 되며, 역 슬래시만 이스케이프 해야 합니다. 예를 들면:>>> digits_re = r'\d+' >>> sample = '/usr/sbin/sendmail - 0 errors, 12 warnings' >>> print(re.sub(digits_re, digits_re.replace('\\', r'\\'), sample)) /usr/sbin/sendmail - \d+ errors, \d+ warnings
버전 3.3에서 변경:
'_'문자는 더는 이스케이프 되지 않습니다.버전 3.7에서 변경: 정규식에서 특별한 의미를 가질 수 있는 문자만 이스케이프 됩니다. 결과적으로,
'!','"','%',"'",',','/',':',';','<','=','>','@'및 ‘”'는 더는 이스케이프 되지 않습니다.
- re.purge()¶
정규식 캐시를 지웁니다.
예외¶
- exception re.PatternError(msg, pattern=None, pos=None)¶
여기에 포함된 함수 중 하나에 전달된 문자열이 유효한 정규 표현식이 아니거나(예: 짝이 맞지 않는 괄호가 포함됨), 컴파일 또는 매칭 과정에서 다른 오류가 발생할 때 예외가 발생합니다. 문자열에 패턴과 일치하는 부분이 없는 것은 결코 오류가 아닙니다.
PatternError인스턴스는 다음과 같은 추가 속성을 가집니다:- msg¶
포맷되지 않은 에러 메시지.
- pattern¶
정규식 패턴.
- pos¶
컴파일이 실패한 위치를 가리키는 pattern의 인덱스 (
None일 수 있습니다).
- lineno¶
pos에 해당하는 줄 (
None일 수 있습니다).
- colno¶
pos에 해당하는 열 (
None일 수 있습니다).
버전 3.5에서 변경: 추가 어트리뷰트가 추가되었습니다.
버전 3.13에서 변경:
PatternError는 원래error라는 이름이었으며, 하위 호환성을 위해 후자의 이름도 별칭으로 유지됩니다.
정규 표현식 객체¶
- class re.Pattern¶
re.compile()에 의해 반환되는 컴파일된 정규 표현식 객체.패턴은 처리하는 문자열 유형(
str또는bytes)에 대한 제네릭 입니다.버전 3.9에서 변경:
re.Pattern은 유니코드(str) 또는 바이트 패턴을 나타내기 위해[]를 지원합니다. 제네릭 에일리어스 형 를 참조하십시오.
- Pattern.search(string[, pos[, endpos]])¶
string 을 스캔하여 이 정규 표현식이 일치하는 첫 위치를 찾고, 해당
Match를 반환합니다. 문자열 내에 패턴과 일치하는 위치가 없으면None을 반환합니다. 이는 문자열의 특정 지점에서 길이 0인 일치를 찾는 것과는 다릅니다.선택적 두 번째 매개 변수 pos는 검색을 시작할 문자열의 인덱스를 제공합니다; 기본값은
0입니다. 이것은 문자열을 슬라이싱하는 것과 완전히 동등하지는 않습니다;'^'패턴 문자는 문자열의 실제 시작 부분과 개행 직후의 위치에서 일치하지만, 검색을 시작할 색인에서 반드시 일치하지는 않습니다.선택적 매개 변수 endpos는 문자열을 어디까지 검색할지를 제한합니다; 문자열이 endpos 문자 길이인 것처럼 취급되어, 일치를 찾기 위해 pos에서
endpos - 1까지의 문자만 검색됩니다. endpos가 pos보다 작으면 일치는 없습니다; 그렇지 않으면, rx가 컴파일된 정규식 객체일 때,rx.search(string, 0, 50)는rx.search(string[:50], 0)와 동등합니다.>>> pattern = re.compile("d") >>> pattern.search("dog") # 인덱스 0에서 일치 <re.Match object; span=(0, 1), match='d'> >>> pattern.search("dog", 1) # 일치 없음; search는 "d"를 포함하지 않음
- Pattern.prefixmatch(string[, pos[, endpos]])¶
string 의 시작 부분에서 0개 이상의 문자가 이 정규 표현식과 일치하면 해당
Match를 반환합니다. 문자열이 패턴과 일치하지 않으면None을 반환합니다. 이는 길이 0인 일치와는 다르다는 점에 유의하십시오.MULTILINE모드에서도 이 기능은 각 줄의 시작이 아닌 문자열 전체의 시작 부분에서만 일치합니다.선택적 pos와 endpos 매개 변수는
search()메서드에서와 같은 의미입니다.>>> pattern = re.compile("o") >>> pattern.prefixmatch("dog") # "o"가 "dog"의 시작 부분에 있지 않으므로 일치 없음. >>> pattern.prefixmatch("dog", 1) # "o"가 "dog"의 두 번째 문자이므로 일치함. <re.Match object; span=(1, 2), match='o'>
string의 임의 위치에서 일치를 찾으려면, 대신
search()를 사용하십시오 (search() 대 prefixmatch()도 참조하십시오).이 메서드는 현재 두 개의 이름을 가지고 있으며, 오랫동안
match()로 알려져 왔습니다. 이전 Python 버전과의 호환성을 유지해야 하는 경우 해당 이름을 사용하십시오.Added in version 3.15.
- Pattern.match(string[, pos[, endpos]])¶
버전 3.15부터 약하게 폐지 <Soft deprecated>:
match()는 보다 명확하게 설명되는 대체 이름인prefixmatch()를 위해 soft deprecated 되었습니다. 의도를 더 잘 표현하기 위해 이 이름을 사용하십시오. 다른 언어와 정규 표현식 구현에서는 표준적으로 match 라는 용어를 Python이 항상search()로 부른 동작을 지칭하는 데 사용합니다. 자세한 내용은 prefixmatch() 대 match() 를 참조하십시오.
- Pattern.fullmatch(string[, pos[, endpos]])¶
string 전체가 이 정규 표현식과 일치하면 해당
Match를 반환합니다. 문자열이 패턴과 일치하지 않으면None을 반환합니다. 이는 길이 0인 일치와는 다르다는 점에 유의하십시오.선택적 pos와 endpos 매개 변수는
search()메서드에서와 같은 의미입니다.>>> pattern = re.compile("o[gh]") >>> pattern.fullmatch("dog") # "o"가 "dog"의 시작 부분에 있지 않으므로 일치 없음. >>> pattern.fullmatch("ogre") # 전체 문자열이 일치하지 않으므로 일치 없음. >>> pattern.fullmatch("doggie", 1, 3) # 주어진 범위 내에서 일치함. <re.Match object; span=(1, 3), match='og'>
Added in version 3.4.
- Pattern.findall(string[, pos[, endpos]])¶
findall()함수와 유사한데, 컴파일된 패턴을 사용합니다. 하지만,search()처럼 검색 영역을 제한하는 선택적 pos와 endpos 매개 변수도 받아들입니다.
- Pattern.finditer(string[, pos[, endpos]])¶
finditer()함수와 유사한데, 컴파일된 패턴을 사용합니다. 하지만,search()처럼 검색 영역을 제한하는 선택적 pos와 endpos 매개 변수도 받아들입니다.
- Pattern.flags¶
정규식 매칭 플래그입니다. 이는
compile`에 전달된 플래그, 패턴 내의 모든 ``(?...)`()인라인 플래그, 그리고 패턴이 유니코드 문자열인 경우와 같은UNICODE등과 같은 암시적 플래그의 조합입니다.
- Pattern.groups¶
패턴에 있는 포착 그룹 수.
- Pattern.groupindex¶
(?P<id>)로 정의된 기호 그룹 이름을 그룹 번호에 매핑하는 딕셔너리. 패턴에 기호 그룹이 사용되지 않으면 딕셔너리는 비어 있습니다.
- Pattern.pattern¶
패턴 객체가 컴파일된 패턴 문자열.
버전 3.7에서 변경: copy.copy()와 copy.deepcopy() 지원이 추가되었습니다. 컴파일된 정규식 객체는 원자적이라고 간주합니다.
일치 객체¶
일치 객체는 항상 불리언 값 True를 가집니다. match()와 search()는 일치가 없을 때 None을 반환하기 때문에, 간단한 if 문으로 일치가 있는지 검사할 수 있습니다:
if match := re.search(pattern, string):
process(match)
- class re.Match¶
성공적인
match나search를 통해 반환된 Match 객체입니다.일치는 매칭된 문자열 유형(
str또는bytes)에 대한 제네릭 입니다.버전 3.9에서 변경:
re.Match는 유니코드(str) 또는 바이트 일치를 나타내기 위해[]를 지원합니다. 제네릭 에일리어스 형 를 참조하십시오.
- Match.expand(template)¶
sub()메서드와 동일하게 템플릿 문자열 template 에 백슬래시 치환을 수행하여 얻은 문자열을 반환합니다.\n과 같은 이스케이프는 적절한 문자로 변환되며, 숫자 역참조(\1,\2) 및 이름 기반 역참조(\g<1>, ` g<name>`)는 해당 그룹의 내용으로 대체됩니다. 역참조 ` g<0>``은 전체 일치 내용으로 대체됩니다.버전 3.5에서 변경: 일치하지 않는 그룹은 빈 문자열로 치환됩니다.
- Match.group([group1, ...])¶
일치의 하나 이상의 서브 그룹을 반환합니다. 인자가 하나인 경우 결과는 단일 문자열이며, 인자가 여러 개인 경우 각 인자당 항목이 하나씩 포함된 튜플이 됩니다. 인자가 없는 경우 group1 은 기본값으로 0(전체 일치가 반환됨)을 가집니다. groupN 인자가 0인 경우 해당 반환 값은 전체 일치 문자열이며, 양의 정수인 경우 해당 괄호로 묶인 그룹과 일치하는 문자열입니다. 그룹 번호가 음수이거나 패턴에 정의된 그룹 수보다 크면
IndexError예외가 발생합니다. 그룹이 일치하지 않은 패턴 부분에 포함되어 있으면 결과는None입니다. 그룹이 여러 번 일치한 패턴 부분에 포함되어 있으면 마지막 일치가 반환됩니다.>>> m = re.search(r"\A(\w+) (\w+)", "Norwegian Blue, pining for the fjords") >>> m.group(0) # 전체 일치 'Norwegian Blue' >>> m.group(1) # 첫 번째 괄호 서브 그룹 'Norwegian' >>> m.group(2) # 두 번째 괄호 서브 그룹 'Blue' >>> m.group(1, 2) # 여러 인자는 튜플을 반환합니다. ('Norwegian', 'Blue')
정규식이
(?P<name>...)문법을 사용하면, groupN 인자는 그룹 이름으로 그룹을 식별하는 문자열일 수도 있습니다. 문자열 인자가 패턴의 그룹 이름으로 사용되지 않으면,IndexError예외가 발생합니다.적당히 복잡한 예:
>>> m = re.search(r"(?P<adjective>\w+) (?P<animal>\w+)", "killer rabbit") >>> m.group('adjective') 'killer' >>> m.group('animal') 'rabbit'
이름있는 그룹은 인덱스로 참조할 수도 있습니다:
>>> m.group(1) 'killer' >>> m.group(2) 'rabbit'
그룹이 여러 번 일치하면, 마지막 일치만 액세스 할 수 있습니다:
>>> m = re.search(r"(..)+", "a1b2c3") # 3회 일치 >>> m.group(1) # 마지막 일치만 반환 'c3'
- Match.__getitem__(g)¶
이것은
m.group(g)와 같습니다. 일치에서 개별 그룹에 더 쉽게 액세스 할 수 있게 합니다:>>> m = re.search(r"(\w+) (\w+)", "Norwegian Blue, pining for the fjords") >>> m[0] # 전체 일치 'Norwegian Blue' >>> m[1] # 첫 번째 괄호 서브 그룹 'Norwegian' >>> m[2] # 두 번째 괄호 서브 그룹 'Blue'
이름이 있는 그룹도 지원됩니다:
>>> m = re.search(r"(?P<adjective>\w+) (?P<animal>\w+)", "killer rabbit") >>> m['adjective'] 'killer' >>> m['animal'] 'rabbit'
Added in version 3.6.
- Match.groups(default=None)¶
1에서 패턴에 있는 그룹의 수까지, 일치의 모든 서브 그룹을 포함하는 튜플을 반환합니다. default 인자는 일치에 참여하지 않은 그룹에 사용됩니다; 기본값은
None입니다.예를 들면:
>>> m = re.search(r"(\d+)\.(\d+)", "24.1632") >>> m.groups() ('24', '1632')
우리가 소수점과 그 이후의 모든 것을 선택적으로 만들면, 모든 그룹이 일치에 참여하지 않을 수 있습니다. 이 그룹은 default 인자가 주어지지 않는 한 기본값
None이 됩니다:>>> m = re.search(r"(\d+)\.?(\d+)?", "24") >>> m.groups() # 두 번째 그룹의 기본값은 None입니다. ('24', None) >>> m.groups('0') # 이제, 두 번째 그룹의 기본값은 '0'입니다. ('24', '0')
- Match.groupdict(default=None)¶
일치의 모든 이름 있는 서브 그룹을 포함하고, 서브 그룹의 이름을 키로 사용하는 딕셔너리를 반환합니다. default 인자는 일치에 참여하지 않은 그룹에 사용됩니다; 기본값은
None입니다. 예를 들면:>>> m = re.search(r"(?P<adjective>\w+) (?P<animal>\w+)", "killer rabbit") >>> m.groupdict() {'adjective': 'killer', 'animal': 'rabbit'}
- Match.start([group])¶
- Match.end([group])¶
group과 일치하는 부분 문자열의 시작과 끝 인덱스를 반환합니다; group의 기본값은 0입니다 (전체 일치 문자열을 뜻합니다). group이 있지만, 일치에 기여하지 않으면,
-1을 반환합니다. 일치 객체 m과 일치에 기여한 그룹 g에서, 그룹 g와 일치하는 부분 문자열(m.group(g)와 동등합니다)은 다음과 같습니다m.string[m.start(g):m.end(g)]
group이 널 문자열과 일치하면
m.start(group)은m.end(group)와 같음에 유의하십시오. 예를 들어,m = re.search('b(c?)', 'cba')이후에,m.start(0)은 1이고,m.end(0)은 2이며,m.start(1)과m.end(1)은 모두 2이고,m.start(2)는IndexError예외를 발생시킵니다.전자 메일 주소에서 remove_this를 제거하는 예:
>>> email = "tony@tiremove_thisger.net" >>> m = re.search("remove_this", email) >>> email[:m.start()] + email[m.end():] 'tony@tiger.net'
- Match.span([group])¶
일치가 m일 때, 2-튜플
(m.start(group), m.end(group))를 반환합니다. group이 일치에 기여하지 않으면, 이것은(-1, -1)임에 유의하십시오. group의 기본값은 0으로, 전체 일치입니다.
- Match.lastindex¶
마지막으로 일치하는 포착 그룹의 정수 인덱스, 또는 그룹이 전혀 일치하지 않으면
None. 예를 들어, 정규식(a)b,((a)(b))및((ab))는 문자열'ab'에 적용될 경우lastindex == 1이 되지만,(a)(b)정규식은 같은 문자열에 적용될 때lastindex == 2가 됩니다.
- Match.lastgroup¶
마지막으로 일치하는 포착 그룹의 이름, 또는 그룹에 이름이 없거나, 그룹이 전혀 일치하지 않으면
None.
버전 3.7에서 변경: copy.copy()와 copy.deepcopy() 지원이 추가되었습니다. 일치 객체는 원자적이라고 간주합니다.
정규식 예제¶
쌍 검사하기¶
이 예제에서는, 다음과 같은 도우미 함수를 사용하여 좀 더 세련되게 일치 객체를 표시합니다:
def displaymatch(match):
if match is None:
return None
return '<Match: %r, groups=%r>' % (match.group(), match.groups())
플레이어의 패를 5문자 문자열로 나타내는 포커 프로그램을 작성하고 있다고 가정해봅시다. “a”는 에이스, “k”는 킹, “q”는 퀸, “j”는 잭, “t”는 10, “2”에서 “9”는 그 값의 카드를 나타냅니다.
주어진 문자열이 유효한 패인지 보려면, 다음과 같이 할 수 있습니다:
>>> valid_hand_re = re.compile(r"^[a2-9tjqk]{5}$")
>>> displaymatch(valid_hand_re.search("akt5q")) # 유효함.
"<Match: 'akt5q', groups=()>"
>>> displaymatch(valid_hand_re.search("akt5e")) # 유효하지 않음.
>>> displaymatch(valid_hand_re.search("akt")) # 유효하지 않음.
>>> displaymatch(valid_hand_re.search("727ak")) # 유효함.
"<Match: '727ak', groups=()>"
마지막 패 "727ak"는 페어, 즉 같은 값의 카드 두 장을 포함합니다. 이것을 정규식과 일치시키려면, 역참조를 다음과 같이 사용할 수 있습니다:
>>> pair_re = re.compile(r".*(.).*\1")
>>> displaymatch(pair_re.prefixmatch("717ak")) # 7의 쌍.
"<Match: '717', groups=('7',)>"
>>> displaymatch(pair_re.prefixmatch("718ak")) # 쌍 없음.
>>> displaymatch(pair_re.prefixmatch("354aa")) # 에이스의 쌍.
"<Match: '354aa', groups=('a',)>"
페어가 어떤 카드로 구성되어 있는지 알아내려면, 다음과 같이 일치 객체의 group() 메서드를 사용할 수 있습니다:
>>> pair_re = re.compile(r".*(.).*\1")
>>> pair_re.prefixmatch("717ak").group(1)
'7'
# prefixmatch()가 None을 반환하며, 이는 group() 메서드를 가지고 있지 않으므로 오류 발생:
>>> pair_re.prefixmatch("718ak").group(1)
Traceback (most recent call last):
File "<pyshell#23>", line 1, in <module>
pair_re.prefixmatch("718ak").group(1)
AttributeError: 'NoneType' object has no attribute 'group'
>>> pair_re.prefixmatch("354aa").group(1)
'a'
scanf() 시뮬레이션¶
Python에는 현재 scanf`와 동일한 기능이 없습니다. 정규식은 일반적으로 :c:func:()!scanf` 포맷 문자열보다 길긴 하지만 더 강력합니다. 아래 표는 scanf() 포맷 토큰과 정규식 사이의 어느 정도 유사한 매핑을 제공합니다.
|
정규식 |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
다음과 같은 문자열에서 파일 이름과 숫자를 추출하려면:
/usr/sbin/sendmail - 0 errors, 4 warnings
다음과 같은 scanf() 형식을 사용합니다:
%s - %d errors, %d warnings
대응하는 정규식은 다음과 같습니다:
(\S+) - (\d+) errors, (\d+) warnings
search() 대 prefixmatch()¶
Python은 정규식에 기반한 다음과 같은 다양한 기본 연산을 제공합니다:
re.prefixmatch()는 문자열의 시작 부분에서만 일치하는지 확인합니다re.search()는 문자열 내 어디에서든 일치하는지 확인합니다 (이것이 Perl의 기본 동작입니다)re.fullmatch()는 전체 문자열이 일치하는지 확인합니다
예를 들면:
>>> re.prefixmatch("c", "abcdef") # 일치하지 않음
>>> re.search("c", "abcdef") # 일치함
<re.Match object; span=(2, 3), match='c'>
>>> re.fullmatch("p.*n", "python") # 일치함
<re.Match object; span=(0, 6), match='python'>
>>> re.fullmatch("r.*n", "python") # 일치하지 않음
'^'로 시작하는 정규식은 search()와 함께 사용하여 문자열 시작 부분의 일치로 제한 할 수 있습니다:
>>> re.prefixmatch("c", "abcdef") # 일치하지 않음
>>> re.search("^c", "abcdef") # 일치하지 않음
>>> re.search("^a", "abcdef") # 일치함
<re.Match object; span=(0, 1), match='a'>
다만 MULTILINE 모드에서 prefixmatch() 는 문자열의 시작 부분에서만 일치하며, '^ 로 시작하는 정규식과 함께 사용하는 search() 는 각 줄의 시작 부분에서 일치합니다.
>>> re.prefixmatch("X", "A\nB\nX", re.MULTILINE) # 일치하지 않음
>>> re.search("^X", "A\nB\nX", re.MULTILINE) # 일치함
<re.Match object; span=(4, 5), match='X'>
prefixmatch() 대 match()¶
왜 match() 함수와 메서드 대신 더 긴 표현인 prefixmatch() 를 권장하나요?
Python에 정규식이 추가된 이후 다른 많은 언어들이 정규식 지원 라이브러리를 도입했습니다. 그러나 가장 인기 있는 그들 중 상당수는 Python의 search() 가 제공하는 위치 제한이 없는 동작을 의미하기 위해 API에서 match 라는 용어를 사용합니다. 따라서 다른 언어에 익숙하고 Python API의 차이점에 익숙하지 않은 사용자들에게 단순한 match 라는 표현은 코드를 읽거나 쓸 때 모호할 수 있습니다.
Python의 철학(python3 -m this)을 인용하자면, “명시적인 것이 암시적인 것보다 낫습니다.” prefixmatch`라는 이름을 읽는 사람은 의도된 의미를 이해할 가능성이 높습니다. 반면에 :func:()!match`를 읽을 때 이 오래된 Python의 함정에 익숙하지 않은 사람은 의도된 동작에 대해 의구심을 가질 수 있습니다.
우리는 30년 넘게 코드에서 사용되어 온 이전 이름인 match() 를 제거할 계획이 없습니다. 이것은 soft deprecated 상태입니다. 이전 버전의 Python을 지원하는 코드는 계속해서 match() 를 사용할 수 있으며, 새로운 코드는 prefixmatch() 를 사용하는 것을 권장합니다.
Added in version 3.15: prefixmatch()
버전 3.15부터 약하게 폐지 <Soft deprecated>: match()
전화번호부 만들기¶
split()는 문자열을, 전달된 패턴으로 구분된 리스트로 분할합니다. 이 메서드는 전화번호부를 만드는 다음 예제에서 보이듯이 텍스트 데이터를 파이썬에서 쉽게 읽고 수정할 수 있는 데이터 구조로 변환하는 데 매우 중요합니다.
먼저, 여기 입력이 있습니다. 보통 파일에서 올 수 있습니다만, 여기서는 삼중 따옴표로 묶인 문자열 문법을 사용합니다.
>>> text = """Ross McFluff: 834.345.1254 155 Elm Street
...
... Ronald Heathmore: 892.345.3428 436 Finley Avenue
... Frank Burger: 925.541.7625 662 South Dogwood Way
...
...
... Heather Albrecht: 548.326.4584 919 Park Place"""
항목은 하나 이상의 개행으로 구분됩니다. 이제 비어있지 않은 각 줄이 항목이 되도록 문자열을 리스트로 변환합니다:
>>> entries = re.split("\n+", text)
>>> entries
['Ross McFluff: 834.345.1254 155 Elm Street',
'Ronald Heathmore: 892.345.3428 436 Finley Avenue',
'Frank Burger: 925.541.7625 662 South Dogwood Way',
'Heather Albrecht: 548.326.4584 919 Park Place']
마지막으로, 각 항목을 이름, 성, 전화번호 및 주소로 구성된 리스트로 분할합니다. 주소에 우리의 분할 패턴인 스페이스가 들어있기 때문에, split()의 maxsplit 매개 변수를 사용합니다:
>>> [re.split(":? ", entry, maxsplit=3) for entry in entries]
[['Ross', 'McFluff', '834.345.1254', '155 Elm Street'],
['Ronald', 'Heathmore', '892.345.3428', '436 Finley Avenue'],
['Frank', 'Burger', '925.541.7625', '662 South Dogwood Way'],
['Heather', 'Albrecht', '548.326.4584', '919 Park Place']]
:? 패턴은 결과 리스트에 나타나지 않도록, 성 뒤의 콜론과 일치합니다. maxsplit로 4를 사용하면, 번지수를 거리 이름과 분리 할 수 있습니다:
>>> [re.split(":? ", entry, maxsplit=4) for entry in entries]
[['Ross', 'McFluff', '834.345.1254', '155', 'Elm Street'],
['Ronald', 'Heathmore', '892.345.3428', '436', 'Finley Avenue'],
['Frank', 'Burger', '925.541.7625', '662', 'South Dogwood Way'],
['Heather', 'Albrecht', '548.326.4584', '919', 'Park Place']]
텍스트 변환¶
sub()는 패턴의 모든 일치를 문자열이나 함수의 결과로 치환합니다. 이 예제는 sub()에 텍스트를 “뒤섞는”, 즉 문장의 각 단어에서 첫 번째 문자와 마지막 문자를 제외한 모든 문자의 순서를 무작위로 바꾸는 함수를 사용하는 방법을 보여줍니다:
>>> def repl(m):
... inner_word = list(m.group(2))
... random.shuffle(inner_word)
... return m.group(1) + "".join(inner_word) + m.group(3)
...
>>> text = "Professor Abdolmalek, please report your absences promptly."
>>> re.sub(r"(\w)(\w+)(\w)", repl, text)
'Poefsrosr Aealmlobdk, pslaee reorpt your abnseces plmrptoy.'
>>> re.sub(r"(\w)(\w+)(\w)", repl, text)
'Pofsroser Aodlambelk, plasee reoprt yuor asnebces potlmrpy.'
모든 부사 찾기¶
findall()은 search()처럼 첫 번째 등장뿐만 아니라, 패턴의 모든 등장과 일치합니다. 예를 들어, 작가가 어떤 텍스트에서 부사를 모두 찾고 싶으면, 다음과 같은 방식으로 findall()을 사용할 수 있습니다:
>>> text = "He was carefully disguised but captured quickly by police."
>>> re.findall(r"\w+ly\b", text)
['carefully', 'quickly']
모든 부사와 그 위치 찾기¶
패턴의 모든 일치에 대해 매칭된 텍스트 외에 더 많은 정보가 필요한 경우, finditer() 는 문자열 대신 Match 객체를 제공하므로 유용합니다. 이전 예제를 계속하자면, 작성자가 어떤 텍스트에서 부사와 그 위치 를 모두 찾으려는 경우 다음과 같이 finditer() 를 사용하면 됩니다:
>>> text = "He was carefully disguised but captured quickly by police."
>>> for m in re.finditer(r"\w+ly\b", text):
... print('%02d-%02d: %s' % (m.start(), m.end(), m.group(0)))
07-16: carefully
40-47: quickly
Raw 문자열 표기법¶
날 문자열 표기법(r"text")은 정규식을 합리적인 상태로 유지합니다. 이것 없이는, 정규식의 모든 역 슬래시('\')를 이스케이프 하기 위해 그 앞에 또 하나의 역 슬래시를 붙여야 합니다. 예를 들어, 다음 두 코드 줄은 기능상으로 같습니다:
>>> re.search(r"\W(.)\1\W", " ff ")
<re.Match object; span=(0, 4), match=' ff '>
>>> re.search("\\W(.)\\1\\W", " ff ")
<re.Match object; span=(0, 4), match=' ff '>
리터럴 역 슬래시와 일치시키려면, 정규식에서 이스케이프 되어야 합니다. 날 문자열 표기법을 사용하면, r"\\"이 됩니다. 날 문자열 표기법을 사용하지 않으면, "\\\\"를 사용해야 하는데, 다음 코드 줄들은 기능적으로 같습니다:
>>> re.search(r"\\", r"\\")
<re.Match object; span=(0, 1), match='\\'>
>>> re.search("\\\\", r"\\")
<re.Match object; span=(0, 1), match='\\'>
토크나이저 작성하기¶
토크나이저나 스캐너는 문자열을 분석하여 문자 그룹을 분류합니다. 이것은 컴파일러나 인터프리터를 작성하는 데 유용한 첫 번째 단계입니다.
텍스트 범주는 정규식으로 지정됩니다. 이 기법은 이들을 하나의 마스터 정규식으로 결합하고 연속적인 일치를 반복하는 것입니다:
from typing import NamedTuple
import re
class Token(NamedTuple):
type: str
value: int | float | str
line: int
column: int
def tokenize(code):
keywords = {'IF', 'THEN', 'ENDIF', 'FOR', 'NEXT', 'GOSUB', 'RETURN'}
token_specification = [
('NUMBER', r'\d+(\.\d*)?'), # 정수 또는 소수점 숫자
('ASSIGN', r':='), # 할당 연산자
('END', r';'), # 문장 종료자
('ID', r'[A-Za-z]+'), # 식별자
('OP', r'[+\-*/]'), # 산술 연산자
('NEWLINE', r'\n'), # 줄 바꿈
('SKIP', r'[ \t]+'), # 공백 및 탭 건너뛰기
('MISMATCH', r'.'), # 기타 모든 문자
]
tok_regex = '|'.join('(?P<%s>%s)' % pair for pair in token_specification)
line_num = 1
line_start = 0
for mo in re.finditer(tok_regex, code):
kind = mo.lastgroup
value = mo.group()
column = mo.start() - line_start
if kind == 'NUMBER':
value = float(value) if '.' in value else int(value)
elif kind == 'ID' and value in keywords:
kind = value
elif kind == 'NEWLINE':
line_start = mo.end()
line_num += 1
continue
elif kind == 'SKIP':
continue
elif kind == 'MISMATCH':
raise RuntimeError(f'{value!r} unexpected on line {line_num}')
yield Token(kind, value, line_num, column)
statements = '''
IF quantity THEN
total := total + price * quantity;
tax := price * 0.05;
ENDIF;
'''
for token in tokenize(statements):
print(token)
토크나이저는 다음과 같은 출력을 생성합니다:
Token(type='IF', value='IF', line=2, column=4)
Token(type='ID', value='quantity', line=2, column=7)
Token(type='THEN', value='THEN', line=2, column=16)
Token(type='ID', value='total', line=3, column=8)
Token(type='ASSIGN', value=':=', line=3, column=14)
Token(type='ID', value='total', line=3, column=17)
Token(type='OP', value='+', line=3, column=23)
Token(type='ID', value='price', line=3, column=25)
Token(type='OP', value='*', line=3, column=31)
Token(type='ID', value='quantity', line=3, column=33)
Token(type='END', value=';', line=3, column=41)
Token(type='ID', value='tax', line=4, column=8)
Token(type='ASSIGN', value=':=', line=4, column=12)
Token(type='ID', value='price', line=4, column=15)
Token(type='OP', value='*', line=4, column=21)
Token(type='NUMBER', value=0.05, line=4, column=23)
Token(type='END', value=';', line=4, column=27)
Token(type='ENDIF', value='ENDIF', line=5, column=4)
Token(type='END', value=';', line=5, column=9)
Friedl, Jeffrey. Mastering Regular Expressions. 3rd ed., O’Reilly Media, 2009. 이 책의 세 번째 판은 더는 파이썬을 다루지 않지만, 초판은 훌륭한 정규식 패턴 작성을 아주 자세하게 다루었습니다.