정규표현식(regex)

Kepler·2020년 4월 1일
0

대부분의 예제와 설명은 파이썬 코딩도장: 43 정규표현식 에서 발췌하였습니다.

정의

정규표현식(regular expression)은 일정한 규칙(패턴)을 가진 문자열을 표현하는 방법입니다. 복잡한 문자열 속에서 특정한 규칙으로 된 문자열을 검색한 뒤 추출하거나 바꿀 때 사용합니다. 또는, 문자열이 정해진 규칙에 맞는지 판단할 때도 사용합니다. (코딩도장)

파이썬에서의 정규표현식 사용하기

re 모듈을 import하여 사용한다.

  • re.match("패턴", "문자열") : 문자열이 처음부터 매칭되는지 판단
import re

re.match("Hello", "Hello, World")
> <_sre.SRE_Match object; span=(0, 5), match='Hello'>
  • re.search("패턴", "문자열") : 문자열 일부분이 매칭되는지 판단
import re

>>> re.search("world", "Hello, world")
<re.Match object; span=(7, 12), match='world'>

>>> re.match("world", "Hello, world") #world가 처음에 오지 않으므로 매치하지 않음
  • 객체 = re.compile('패턴'): 자주 쓰는 패턴인 경우, 패턴을 객체로 만들어 match/search 뒤에서 호출
>>> p = re.compile('[0-9]+')    # 정규표현식 패턴을 객체로 만듦
>>> p.match('1234')             # 정규표현식 패턴 객체에서 match 메서드 사용
<_sre.SRE_Match object; span=(0, 4), match='1234'>
>>> p.search('hello')           # 정규표현식 패턴 객체에서 search 메서드 사용

정규표현식 기초

^문자열: 문자열이 맨 앞에 오는지 판단
$문자열: 문자열이 맨 뒤에 오는지 판단
문자열|문자열: 특정 문자열에서 지정된 문자가 하나라도 포함되는지 판단 (or 연산자)

import re

>>> re.search('^Hello', 'Hello, world!')     # Hello로 시작하므로 패턴에 매칭됨
<_sre.SRE_Match object; span=(0, 5), match='Hello'>

>>> re.search('world!$', 'Hello, world!')    # world!로 끝나므로 패턴에 매칭됨
<_sre.SRE_Match object; span=(7, 13), match='world!'>

>>> re.match('hello|world', 'hello')    # hello 또는 world가 있으므로 패턴에 매칭됨
<_sre.SRE_Match object; span=(0, 5), match='hello'>

[0-9]* 또는 [0-9]+ : 숫자가 포함되는지 판단

  • 대괄호안에 숫자를 넣는다 (0-9로 숫자범위를 표현한다)

  • *는 숫자가 0개이상 있는지 확인한다.

  • +는 숫자가 1개이상 있는지 확인한다.

>>> re.match('a*b', 'b')      # b에는 a가 0개 이상 있으므로 패턴에 매칭됨
<_sre.SRE_Match object; span=(0, 1), match='b'>

>>> re.match('a+b', 'b')      # b에는 a가 1개 이상 없으므로 패턴에 매칭되지 않음

>>> re.match('a*b', 'aab')    # aab에는 a가 0개 이상 있으므로 패턴에 매칭됨
<_sre.SRE_Match object; span=(0, 3), match='aab'>

>>> re.match('a+b', 'aab')    # aab에는 a가 1개 이상 있으므로 패턴에 매칭됨
<_sre.SRE_Match object; span=(0, 3), match='aab'>

문자?: ? 앞의 문자가 0 or 1개인지 판단
.: . 의 위치에 아무 문자(숫자)가 1개 있는지 판단

>>> re.match('abc?d', 'abd')         # abd에서 c 위치에 c가 0개 있으므로 패턴에 매칭됨
<_sre.SRE_Match object; span=(0, 3), match='abd'>

>>> re.match('ab[0-9]?c', 'ab3c')    # [0-9] 위치에 숫자가 1개 있으므로 패턴에 매칭됨
<_sre.SRE_Match object; span=(0, 4), match='ab3c'>

>>> re.match('ab.d', 'abxd')         # .이 있는 위치에 문자가 1개 있으므로 패턴에 매칭됨
<_sre.SRE_Match object; span=(0, 4), match='abxd'>

문자{개수} 또는 (문자열){개수} : 문자가 개수만큼 있는지 판단

>>> re.match('h{3}', 'hhhello')
<_sre.SRE_Match object; span=(0, 3), match='hhh'>

>>> re.match('(hello){3}', 'hellohellohelloworld')
<_sre.SRE_Match object; span=(0, 15), match='hellohellohello'>

# 휴대전화 번호가 형식(000-0000-0000) 에 맞는지를 판단하는 정규표현식
>>> re.match('[0-9]{3}-[0-9]{4}-[0-9]{4}', '010-1000-1000')    # 숫자 3개-4개-4개 패턴에 매칭됨
<_sre.SRE_Match object; span=(0, 13), match='010-1000-1000'>

# 전화번호가 형식에 맞는지 판단하는 정규 표현식 (첫번째 지역번호는 2~3자리, 두번째 번호도 3~4가 될 수 있다)
>>> re.match('[0-9]{2,3}-[0-9]{3,4}-[0-9]{4}', '02-100-1000')    # 2~3개-3~4개-4개 패턴에 매칭됨
<_sre.SRE_Match object; span=(0, 11), match='02-100-1000'>

[a-zA-Z-0-9]+ : 영문과 숫자 조합이 있는지 판단
[가-힣]+: 한글이 있는지 판단

>>> re.match('[a-zA-Z0-9]+', 'Hello1234')    # a부터 z, A부터 Z, 0부터 9까지 1개 이상 있으므로
<_sre.SRE_Match object; span=(0, 9), match='Hello1234'> 

[^범위]* 또는 [^범위]+ : 해당 범위를 재외한 문자가 0 또는 1개이상 있는지 판단

  • 특정 문자열로 시작할 경우와 달리, ^대괄호 안에 넣어준다.
>>> re.match('[^A-Z]+', 'Hello')    # 대문자를 제외. 대문자가 있으므로 패턴에 매칭되지 않음

>>> re.match('[^A-Z]+', 'hello')    # 대문자를 제외. 대문자가 없으므로 패턴에 매칭됨
<_sre.SRE_Match object; span=(0, 5), match='hello'>

>>> re.search('[0-9]+$', 'Hello1234')    # 숫자로 끝나므로 패턴에 매칭됨
<_sre.SRE_Match object; span=(5, 9), match='1234'>

\특수문자 : 특수문자가 들어있는지 판단

>>> re.search('\*+', '1 ** 2')   # *이 1개이상 들어있는지 판단
<_sre.SRE_Match object; span=(2, 4), match='**'>

>>> re.match('[$()a-zA-Z0-9]+', '$(document)')    # $, (, )와 문자, 숫자가 들어있는지 판단
<_sre.SRE_Match object; span=(0, 11), match='$(document)'>

\d: [0-9]와 같음. 모든 숫자
\D: [^0-9]와 같음. 숫자를 제외한 모든 문자
\w: [a-zA-Z0-9_]와 같음. 영문 대소문자, 숫자, 밑줄 문자
\W: [^a-zA-Z0-9_]와 같음. 영문 대소문자, 숫자, 밑줄 문자를 제외한 모든 문자

>>> re.match('\d+', '1234')          # 모든 숫자이므로 패턴에 매칭됨
<_sre.SRE_Match object; span=(0, 4), match='1234'>

>>> re.match('\D+', 'Hello')         # 숫자를 제외한 모든 문자이므로 패턴에 매칭됨
<_sre.SRE_Match object; span=(0, 5), match='Hello'>

>>> re.match('\w+', 'Hello_1234')    # 영문 대소문자, 숫자, 밑줄 문자이므로 패턴에 매칭됨
<_sre.SRE_Match object; span=(0, 10), match='Hello_1234'>

>>> re.match('\W+', '(:)')    # 영문 대소문자, 숫자, 밑줄문자를 제외한 모든 문자이므로 패턴에 매칭됨
<_sre.SRE_Match object; span=(0, 3), match='(:)'>

\s or '': 공백처리
\S: 공백제외

>>> re.match('[a-zA-Z0-9 ]+', 'Hello 1234')     # 0-9뒤에' '로 공백 표현
<_sre.SRE_Match object; span=(0, 10), match='Hello 1234'>

>>> re.match('[a-zA-Z0-9\s]+', 'Hello 1234')    # \s로 공백 표현
<_sre.SRE_Match object; span=(0, 10), match='Hello 1234'>

정규표현식 그룹

(정규표현식) (정규표현식) : ()괄호로 정규표현식 그룹을 나누어, 해당 그룹과 일치하는 문자열을 얻어올 때 사용.
매치객체.group(그룹숫자) : 각 그룹에 해당하는 문자열 가져옴.
매치객체.groups(그룹숫자) : 각 그룹에 해당하는 문자열을 튜플로 가져옴.

#공백으로 정규표현식/문자열 페어를 두 그룹으로 나눔
>>> m = re.match('([0-9]+) ([0-9]+)', '10 295') 

>>> m.group(1)    # 첫 번째 그룹(그룹 1)에 매칭된 문자열을 반환
'10'
>>> m.group(2)    # 두 번째 그룹(그룹 2)에 매칭된 문자열을 반환
'295'
>>> m.group()     # 매칭된 문자열을 한꺼번에 반환 (=m.group(0))
'10 295'

re.findall('패턴','문자열') : 그룹에 관게없이 패턴에 매칭되는 모든 문자열 가져오기

>>> re.findall('[0-9]+', '1 2 Fizz 4 Buzz Fizz 7 8')
['1', '2', '4', '7', '8']
  • *, + 그룹 활용하기 :
    (.[a-z]+)*는 점과 영문 소문자가 1개 이상 있는지 판단하고, 이 그룹이 0개 이상인지 판단한다.
>>> re.match('[a-z]+(.[a-z]+)*$', 'hello.world')    # .world는 문자열이므로 패턴에 매칭됨
<_sre.SRE_Match object; span=(0, 11), match='hello.world'>

>>> re.match('[a-z]+(.[a-z]+)*$', 'hello.1234')     # .1234는 숫자이므로 패턴에 매칭되지 않음

>>> re.match('[a-z]+(.[a-z]+)*$', 'hello')          # .뒤에 문자열이 없어도 패턴에 매칭됨
<_sre.SRE_Match object; span=(0, 5), match='hello'>
profile
🔰

0개의 댓글