본문 바로가기
Python

[Python] Regular Expression : 표현식 기초 및요약

by ds31x 2023. 7. 3.

Regular Expression :  정규표현식 요약

 

Regular Expression (re) 의 기본적인 operator는 다음과 같음.

Basic operator Description
. Any character except `\n` (newline)
a The character a itself
ab The string ab itself
x|y x or y
\y Escapes a special character y, such as ^+{}$()[]|\-?.*
  • backslash 는 escape sequence로 동작을 의미함 :
    • 즉, 뒤에 오는 문자와 결합하여 newline이나 tab등을 의미하게 됨.
  • 반대로 특수한 의미를 가지는 문자들(^+{}$()[]|\-?.*)이 backslash 뒤에 오면, 자신의 특수한 의미를 잃고 그 문자 자체를 의미.
  • a 글자 그대로를 가르킨다는 것은 a 라고 기재된 literal을 의미한다는 것임.

기본 Escape Sequence

기본적인 escape sequence들의 예는 다음과 같음.

Escaped characters (or Escaped sequence) name
\n Newline
\r Carriage return
\t Tab
  • 사실 backslash는 Python에서 escape character라고 불림.
  • 그 뒤에 놓이는 character가 본래 가지는 기능에서 escape시킨다고 생각할 수 있음.
  • backslash 자체를 출력하기 위해서는 \\ 를 사용. (escape하는 기능에서 escape?)
  • raw string에서는 backslash가 일반 글자로 처리됨 :

다음의 두 라인은 모두 backslash를 글자 자체로 처리하여 출력하고, 그 뒤에 n이 놓임.

'\\n'
r'\n'
여기서 raw string을 다룬 이유는
RE의 expression들은 backslash를 매우 빈번하게 사용하기 때문에,
Python의 경우 기본 escape sequence와 충돌을 피하기 위해 raw string을 사용하는 경우가 일반적이기 때문임. 

Regular Expression에서의 Character Classes

RE의 기본 character classes는 다음과 같음.

Character classes Description
[a-d] One character of: a,b,c,d (문자클래스)
정확히는 a or b or c or d
a|b|c|d
[^a-d] One character except: a,b,c,d
not (a or b or c or d)
\d One digit
\D One non-digit
\s One whitespace character
\S One non-whitespace
\w One alphanumeric character
\W One non-alphanumeric character
  • square bracket은 하나의 글자(character)를 의미
  • square bracket안의 dash는 범위를 의미(알파벳 순).
  • square bracket안의 caret은  complement를 의미하여 "여집합"을 의미하게 됨.
  • d 는 digit으로 숫자를 의미하고, 대문자 D 는 Non digit을 의미함. 
  • 즉, 대문자는 Non을 의미한다.

Python의 string의 printable을 통해 위의 character classes를 확인해보는 코드는 다음과 같음.

import string
import re
printable = string.printable
print(f'len of printable {len(printable)}')
print(printable)
print('-------------------')
print('digits')
print(re.findall('\d', printable))

print('white space')
print(re.findall('\s', printable)) # space, tab, newline, carriage return, vertical tab, and form feed.

print('alphanumeric')
print(re.findall('\w', printable))

# -----------------------
#  Test for unicode
x = 'abc' + '-/*' + '\u00ea' + '\u0115'
print(re.findall('\w', printable))
print(re.findall('\W', printable))

RE's Quntifiers

RE의 기본 Quntifiers (반복횟수, 갯수 등을 지정)은 다음과 같음.

Quantifiers Description
x* Zero or more xs
x+ One or more xs
x? Zero or one x (=Optional of the preceding character)
x{2} Exactly two xs
x{2,5} Between two and five xs
  • 앞서 살펴본 문자나 숫자들이 몇번 나타나는지 등등의 지정이 위의 Qunatifier를 통해 수행됨.
아래 내용들은 정규표현식에 대한 좀 더 세부 내용이나,
위의 내용들은 기본적 상식으로 알고 있는 게 좋은 것들로 차이가 있음

RE's Assertion

다음은 RE의 Assertion들로

실제로 다른 문자열을 매칭시키지 않으면서 그 자리에서 앞이나 뒤에 해당하는 패턴이 존재하는 지만 확인 (확인만 할 뿐 해당 부분은 matching에 포함되지 않음) 하는 방식으로 동작.

Assertions Description
^ Start of string, Caret
\b Word boundary (between a \w and a \W, in either order)
\B Non-word boundary
$ End of string, Dollar sign
prev (?= next ) prev if followed by next
(?<= prev ) next next if preceded by prev
(?<! prev ) next next if not preceded by prev
  • 주의할 점은 \b Python의 string에서 escape sequence로 backspace이라는 점임..
  • 하지만 RE에서는 한 단어의 시작을 의미함. 
  • 이를 제대로 동작시키기 위해서는 앞서 살펴본대로 raw string으로 처리해야 한다.

다음 예제를 확인하라.

source = '''I wish I may, I wish I might
Have a dish of fish tonight.'''

print(re.findall('^I wish', source))
print(re.findall('^wish', source))
print(re.findall('I (?=wish)', source))
print(re.findall('(?<=I) wish', source))

print('===============')
print(re.findall('\bfish', source))
print(re.findall(r'\bfish', source))

RE's Group

다음은 RE에서 group을 지정하는 방법을 보여줌.

Groups Description
(x) Capturing group
(matching된 반환값에 포함됨.)
(?:x) Non-capturing group
(matching에서는사용되나 반환값에 포함되지 않음)
  • RE에서 해석되는 우선순위 등을 조절하기 위해 Group으로 묶는 경우도 있음. 
  • RE가 반환하는 match된 문자열들도 지정한 group으로 나누어질 수 있음.

다음은 group이 RE의 output에 미치는 영향을 간략히 보여줌.

m = re.search(r'(. dish\b).*(\bfish)', source)
print(m.group())
print(m.groups()) # list로 RE로 지정한 그룹이 나누어 들어감.

그룹 이름 지정.

다음은 RE가 여러 문자열을 반환하는 경우 접근을 쉽게하기 위해 이름을 지정하는 방법을 보여줌.

Naming Description
(?P<nameexpr) match expr,
saving the match in group name
  • expr 에 해당하는 expression에 매칭된 그룹의 이름이 name이 된다.

다음 예를 확인하라.

m = re.search(r'(?P<DISH>. dish\b).*(?P<FISH>\bfish)', source)
print(m.group())
print(m.group('DISH')) # 지정한 이름으로 group접근.
print(m.group('FISH'))

'Python' 카테고리의 다른 글

[Python] binary file : write and read  (0) 2023.07.04
[Python] Text File : read and write  (0) 2023.07.04
[Python] file : open and close  (0) 2023.07.04
[Python] venv : Python Virtual Envrionment  (0) 2023.06.30
[Python] pip 사용법  (0) 2023.06.30