코학다식

[파이썬(Python)] 정규 표현식 알아보기(2) 본문

Programming/Python

[파이썬(Python)] 정규 표현식 알아보기(2)

copeng 2019. 8. 29. 01:09

파이썬 정규 표현식 알아보기 (2)

 

 

match 객체의 메서드


 

  • match 객체의 메서드들은 다음과 같다.

 

method 목적
group() 매치된 문자열을 돌려준다.
start() 매치된 문자열의 시작 위치를 돌려준다.
end() 매치된 문자열의 끝 위치를 돌려준다.
span() 매치된 문자열의 (시작, 끝)에 해당하는 튜플을 돌려준다.

 

예시 코드를 보자.

>>> p = re.compile('[a-z]+')
>>> m = p.match("python")
>>> m.group()
'python'
>>> m.start()
0
>>> m.end()
6
>>> m.span()
(0, 6)
>>>

예시 코드의 결과에서 주의해야 할 것은 match를 수행한 결과로 돌려준 match 객체의 start()의 결괏값은 항상 0일수밖에 없다는 점이다. 왜냐하면 match 메서드는 문자열의 시작부터 조회하기 때문이다.

 

모듈 단위로 수행하기


 

  • re.compile을 사용하여 컴파일된 패턴 객체로 작업을 수행하는 것 말고도, re 모듈은 이것을 축약한 형태로 사용할 수 있는 방법을 제공한다.
p = re.compile('[a-z]+')
m = p.match("python")

# 위 코드와 아래 코드는 같은 의미이다.

m = re.match('[a-z]+', "python")

 

컴파일 옵션


 

  • 정규식을 컴파일할 때 다음 옵션을 사용할 수 있다.

 

Option 목적
DOTALL(S) .이 줄바꿈 문자를 포함하여 모든 문자와 매치될 수 있도록 한다.
IGNORECASE(I) 대소문자에 관계없이 매치할 수 있도록 한다.
MULTILINE(M) 여러 줄과 매치할 수 있도록 한다. (^, $ 메타 문자의 사용과 관계 있는 옵션이다)
VERBOSE(X) verbose 모드를 사용할 수 있도록 한다. (정규식을 보기 편하게 만들 수 있고 주석 등을 사용할 수 있게 된다)

 

  • 옵션을 사용할 때는 re.DOTALL처럼 전체 옵션 이름을 써고 되고 re.S처럼 약어를 써도 된다.

 

DOTALL, S


 

  • . 메타 문자는 줄바꿈 문자(\n)을 제외한 모든 문자와 매치된다.
  • \n 문자도 포함하여 매치하고 싶다면 re.DOTALL 또는 re.S 옵션을 사용한다.

 

이 옵션은 아래와 같이 사용할 수 있다.

>>> import re
>>> p = re.compile('a.b')
>>> m = p.match('a\nb')
>>> print(m)
None
>>> p = re.compile('a.b', re.DOTALL)
>>> m = p.match('a\nb')
>>> print(m)
<re.Match object; span=(0, 3), match='a\nb'>
>>>

 

IGNORECASE, I


 

  • re.IGNORECASE 또는 re.I 옵션은 대소문자 구별 없이 매치를 수행한다.
>>> p = re.compile('[a-z]')
>>> m = p.match('python')
>>> print(m)
<re.Match object; span=(0, 1), match='p'>
>>> m = p.match('PYTHON')
>>> print(m)
None # 대문자인 경우 매치되지 않음
>>> p = re.compile('[a-z]', re.I) # re.I 옵션 추가
>>> m = p.match('python')
>>> print(m)
<re.Match object; span=(0, 1), match='p'>
>>> m = p.match('PYTHON')
>>> print(m)
<re.Match object; span=(0, 1), match='P'>
>>>

[a-z] 정규식은 소문자만을 의미하지만 re.I 옵션을 함께 사용했을 때는 대소문자 구별 없이 매치되는 것을 볼 수 있다.

 

MULTILINE, M


 

  • re.MULTILINE 또는 re.M 옵션은 메타 문자 ^, $와 연관된다.
  • ^는 문자열의 처음, $는 문자열의 마지막을 의미한다.
  • 가령, 정규식이 ^python인 경우 문자열의 처음은 항상 python으로 시작해야 매치된다. python$인 경우 문자열의 마지막은 항상 python이어야 매치된다.

 

import re
p = re.compile("^python\s\w+")

data = """python one
life is too short
python two
you need python
python three"""

print(p.findall(data))

^python\s\w+은 python이라는 문자열로 시작하고 그 뒤에 whitespace, 그 뒤에 단어가 와야 한다는 의미이다. 이 스크립트를 실행하면 [python one]이라는 결과를 돌려준다. ^에 의해 python이라는 문자열을 사용한 첫 번째 줄만 매치된 것이다.

만약 ^ 메타 문자를 문자열 전체의 처음이 아니라 각 라인의 처음으로 인식시키고 싶다면 re.MULTILINE 또는 re.M을 사용하면 된다.

 

import re
p = re.compile("^python\s\w+", re.MULTILINE)

data = """python one
life is too short
python two
you need python
python three"""

#outputs ['python one', 'python two', 'python three']
print(p.findall(data))

 

VERBOSE, X


 

  • 정규식을 주석 또는 줄 단위로 구분하고 싶다면 re.VERBOSE 또는 re.X 옵션을 사용하면 된다.
  • re.VERBOSE 옵션을 사용하면 문자열에 사용된 whitespace는 컴파일할 때 제거된다. (단, [] 안에 사용한 whitespace는 제외)
  • re.VERBOSE 옵션을 사용하면 줄 단위로 # 기호를 사용하여 주석문을 작성할 수 있다.
  • 가령, 아래의 코드처럼 사용할 수 있다. 같은 정규식이다.

 

# Too difficult to read!
charref = re.compile(r'&[#](0[0-7]+|[0-9]+|x[0-9a-fA-F]+);')

# Much better to read
charref = re.compile(r"""
 &[#]                # Start of a numeric entity reference
 (
     0[0-7]+         # Octal form
   | [0-9]+          # Decimal form
   | x[0-9a-fA-F]+   # Hexadecimal form
 )
 ;                   # Trailing semicolon
""", re.VERBOSE)

 

백슬래시 문제


 

  • 정규 표현식에서 백슬래시(\)는 종종 혼란을 준다.

  • 이를 예방하기 위해 정규식에서 사용한 \가 문자임을 알려 주도록 백슬래시 2개를 사용하여 이스케이프 처리를 해야 한다.

  • 그런데 이는 복잡해지기 쉬우므로 Raw String 규칙이 생겨났다.

 

다음 예시를 보자. "\section" 문자열을 찾기 위한 정규식을 만들 것이다.

\section

 

이 정규식은 \s 문자가 whitespace로 해석된다. 그래서 다음과 동일한 의미가 된다.

[ \t\n\r\f\v]ection

 

의도한 대로 매치하고 싶다면 다음과 같이 변경해야 한다.

\\section

# 컴파일하려면...
p = re.compile('\\section')

그런데 여기서 또 문제가 발생한다. 위에서처럼 정규식을 만들어 컴파일하면 실제 정규식 엔진(정규식을 해석하고 수행하는 모듈)에는 파이썬 문자열 리터럴 규칙에 따라 \\\로 변경되어 \section이 전달된다.

따라서 정규식 엔진에 \\ 문자를 전달하려면 파이썬은 백슬래시를 4개 사용해야 한다.

 

p = re.compile('\\\\section')

백슬래시를 여러 개 쓰는 정규식은 보기에 너무 복잡할 것이다. 이 문제로 파이썬 정규식에는 Raw String 규칙이 생겨났다. 컴파일해야 하는 정규식이 Raw String임을 알려 줄 수 있는 문법을 만든 것이다.

 

p = re.compile(r'\\section')

위와 같이 정규식 앞에 r을 쓰면 Raw String 규칙에 의해 백슬래시 2개를 써도 1개를 쓴 것과 동일해진다.

Comments