본문 바로가기

진리는어디에/Python

Python 정규 표현식

Python

메타 문자

  • 반복 메타문자
문자 의미
* 0 회 이상 반복 ca*t => ct, cat, caat, caaat, …
+ 1 회 이상 반복 ca+t => cat, caat, caaat …
? 0회 혹은 1 ca?t => ct, cat
{m}  m회 반복 ca{2}t => caat
{m, n}  m회부터 n회까지 반복 ca{2, 4}t => caat, caaat, caaaat
>>> import re

>>> re.match('cat', 'caat').group()
'caat'

>>> re.match('cat', 'cat').group()
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
AttributeError: 'NoneType' object has no attribute 'group'

>>> re.match('cat', 'cat').group()
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
AttributeError: 'NoneType' object has no attribute 'group'

>>> re.match('cat', 'caat').group()
'caat'

>>> re.match('cat', 'caaat').group()
'caaat'

>>> re.match('cat', 'caaaat').group()
'caaaat'

>>> re.match('cat', 'caaaaat').group()
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
AttributeError: 'NoneType' object has no attribute 'group'
  • 최소 매칭
기호 의미
*? * 와 같으나 문자열을 최소로 매칭한다.
+? + 와 같으나 문자열을 최소로 매칭한다.
?? ? 와 같으나 문자열을 최소로 매칭한다.
  {m,n}와 같으나 문자열을 최소로 매칭한다.
  • 매칭 메타 문자
메타 문자 의미
. 개행 문자를 제외한 모든 문자와 매칭 된다. re.DOTALL 플래그가 셋팅되어져 있다면 줄바꿈 문자 까지도 매칭 대상에 포함된다.
^ 문자열의 시작과 매칭된다.
re.MULTILINE 모드에서는 각 라인의 시작과 매칭된다.
[] 메타기호 안에서는 반대의 문자열을 취한다
) [^a-zA-Z0-9] 모든 알파벳과 숫자를 제외한 것 들과 매칭된다
$ 문자열의 마지막 또는 문자열 끝의 개행 문자와 매칭되며, MULTILINE 모드 역시 개행 문자의 앞까지 매칭된다. ‘foo$’가 오직 foo 매칭되는 것과는 반대로 foo foo foobar 다 매칭된다. 흥미로운 것은 foo.$ ‘foo1\nfoo2\n’에서 찾는다면 foo2는 매치가 되지만 foo1MULTILINE 모드에서만 매칭이 된다는 것이다.
[] 문자 집합을 나타낸다. [abc]‘a’, ‘b’, ‘c’ 문자 중 하나를 의미한다. [a-c]와 같이 나타낼 수도 있다.
| a|b 는 해당 문자가 ‘a’이거나 ‘b’라는 뜻이다.
() 규식을 그룹으로 묶는다. 이것은 match 또는 search를 통해 리턴되는 Match 오브젝트의 group를 호출할 때 사용된다.
  • 이스케이프 문자
문자 설 명
\\ 역슬래쉬 문자
\d 모든 숫자와 매칭된다 [0-9]
\D 숫자가 아닌 모든 문자와 매칭된다 [^0-9]
\s 모든 화이트 스페이스 문자와 매칭된다 [\t\n\r\f\v]
\S 화이트 스페이스가 아닌 모든 문자와 매칭된다. [^\t\n\r\f\v]
\w 모든 숫자 또는 문자와 매칭된다. [a-zA-Z0-9]
\W 숫자 또는 문자가 아닌 모든 문자와 매칭된다 [^a-zA-Z0-9]
\b 단어의 경계를 나타낸다. 단어는 영문자 혹은 숫자의 연속 문자열로 가정한다.
\B \b의 반대로 단어의 경계가 아님을 나타낸다.
NOTE - 메타 문자를 정규 표현식에 일반 문자로써 사용하려 한다면 '\'문자를 앞에 붙여 준다. 예를 들어 "/*" 와 같이 '*'를 정규 표현식에서 사용 하면 '/'문자가 0회 이상 반복 되는 것으로 인식한다. 그래서 "/\*" 처럼 이스케이프 문자를 앞에 넣어 주어 일반 문자로 사용한다는 것을 알려 주어야 한다.

파이썬 정규 표현식 모듈 re(regular expression)

  • match(<정규표현식>, <대상문자열>)
    대상 문자열의 처음부터 정규식과 매칭 되는지 검사
  • search(<정규표현식>, <대상문자열>)
    대상 문자열 전체를 정규식과 매칭 되는지 검사
  • findall(<정규표현식>, <대상문자열>)
    대상 문자열에서 정규 표현식과 매칭되는 모든 문자열을 리스트 형태로 리턴
  • finditer(<정규표현식>, <대상문자열>)
    대상 문자열에서 정규 표현식과 매칭되는 모든 문자열을 반복 가능한 객체로 리턴

파이썬 정규 표현식 모듈 사용 예제

@Condition이라는 임의 정의된 C++ 주석이 있다면, @Type의 내용을 출력하라.

/*  @Condition
    @Type : ConditionType
*/

아래는 정규 표현식 모듈을 사용한 파이썬 코드다.

import re

f = open(file_path, "r", encoding='UTF8')

for line in f :
    match = re.search('/\*[ \t]*@Condition', line)
    if None != match :
        ... 파싱 시작 ...
        
    match = re.search('@Type+[ \t]*:[ \t]*', line)
    if None != match :
        type = line[match.span()[1]:].rstrip()
        
    match = re.search('\*/', line)
    if None != match :
        ... 파싱 종료 ...
  • re.search 는 대상 문자열 전체를 대상으로 매칭 되는 문자열이 있는지 검사한다. 매칭 되는 문자열이 있는 경우 매칭 정보가 담겨 있는 Match 객체를, 그렇지 않은 경우 None을 리턴한다.
  • Match 객체는 매칭된 문자열의 시작과 끝 위치를 알려주는 span과 매치된 문자열을 알려주는 match 가 있다.
  • '/\*[ \t]*@Condition'
    • /로 시작하고, 바로 뒤에 * 문자를 찾는다. \* 형태인 이유는 *가 메타문자이기 때문에 /문자가 0회 이상 반복 되는 패턴을 찾으려고 한다. *을 리터럴 문자로 사용하기 위해 앞에 이스케이프 문자를 추가 했다.
    • [ \t]* : 문자 집합을 나타내는 대괄호. 대괄호 안에 있는 문자 중 하나와 매칭 되는 문자를 찾는다. 공백과, \t는 일반적으 화이트 스페이스라고 부르며 공백을 의미한다. 뒤의 *는 0회 이상을 반복을 나타낸다.
    • @Condition : 찾는 문자열

부록 1. 같이 보면 좋은 글

유익한 글이었다면 공감(❤) 버튼 꾹!! 추가 문의 사항은 댓글로!!