ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • TIL.55 Python 정규표현식 사용하기
    TIL/Python 2020. 12. 3. 17:20
    728x90

    정규표현식 사용하기

    정규표현식 (regular expression)은 일정한 규칙(패턴)을 가진 문자열을 표현하는 방법이다.

    복잡한 문자열 속에서 특정한 규칙으로 된 문자열을 추출하거나 바꿀때 사용하며

    또한, 문자열이 정해진 규칙에 맞는지 판단할때도 사용한다.

    쪼개서 학습하면 이해가 빠르다고 한다.

     

    정규 표현식은 re 모듈을 가져와서 하용하며 match 함수와 serch 함수를 사용한다.


    문자열 판단하기

    특정 문자열이 포함되어 있는지 판단해보자

    • re.match('패턴', '문자열')

    >>> import re
    >>> re.match('Hello', 'Hello, world!')     # 문자열이 있으므로 정규표현식 매치 객체가 반환됨
    <_sre.SRE_Match object; span=(0, 5), match='Hello'>
    >>> re.match('Python', 'Hello, world!')    # 문자열이 없으므로 아무것도 반환되지 않음

    문자열이 있으면 -> 매치객체(SRE_Match)로 반환

    문자열이 없을 경우 -> 아무것도 반환하지 않음

    사실 아래와 같으 fine method를 이용해 사용할 수 있으며

    그럼 find 함수를 쓸 수 없는 경우에 대해 알아보자.

    'Hello, world!'.find('Hello')

    문자열이 맨 앞에 오는지 맨 뒤에 오는지 판단하기

    정규표현식으로 특정 문자열이 앞에 오는지 뒤에 오는지 판단할 수 있다.

    단 이때는 match 함수가 아닌 search 함수를 사용하여 판단해야 한다.

    match -> 문자열 처음부터 매칭되는지 판단

    search -> 문자열 일부분이 매칭되는지 판단

    ^문자열a -> 문자열a가 맨 앞에 오는지 판단

    문자열a$ -> 문자열a가 맨 뒤에 오는지 판단

    • ^문자열
    • 문자열$
    >>> 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!'>

    지정된 문자열이 "하나" 라도 포함되는지 판단하기

    " | " -> 역슬레쉬 대문자 --> 특정 문자열에서 지정된 문자열(문자)가 하나라도 포함되는지 판단

    OR 연산자와 개념이 같다.

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

    범위 판단하기

     

    문자열이 문자(숫자)로 되어있는 범위로 판단하기

    [](대괄호) 안에 숫자 범위를 넣으며 *  또는 + 를 붙혀 판단한다.

    " * " -> 문자(숫자)가 0개 이상인지

    " + " -> 문자(숫자)가 1개 이상인지

    • [0-9]*
    • [0-9]+
    >>> re.match('[0-9]*', '1234')    # 1234는 0부터 9까지 숫자가 0개 이상 있으므로 패턴에 매칭됨
    <_sre.SRE_Match object; span=(0, 4), match='1234'>
    >>> re.match('[0-9]+', '1234')    # 1234는 0부터 9까지 숫자가 1개 이상 있으므로 패턴에 매칭됨
    <_sre.SRE_Match object; span=(0, 4), match='1234'>
    >>> re.match('[0-9]+', 'abcd')    # abcd는 0부터 9까지 숫자가 1개 이상 없으므로 패턴에 매칭되지 않음

     

    *, + 활용하기

    아래에서 b는 가장 오른쪽 문자열을 지칭하는 용도로 이해하자

    >>> 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'>

    a* a0개 이상 있어야 하므로 b는 매칭이 된다. 하지만 a+ a1개 이상 있어야 하므로 b는 매칭되지 않는다.


    문자가 "한 개" 만 있는지 판단하기

    문자가 여러 개 있는지 판단할때 -> *    + 를 사용하였다

    문자가 한 개만 있는지 판단해보자

    ? -> ?앞의 문자(범위)가 0개 또는 1개 인지 판단

    . -> .이 있는 위치아무 문자(숫자)가 1개 인지 판단

    • 문자?
    • [0-9]?
    • .
    >>> 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'

    문자 개수 판단하기

    문자(숫자)가 정확히 몇 개 있는지 판단해보자

    문자 뒤에 {개수}를 지정

    문자열의 경우 괄호로 묶고 뒤에 {개수} 지정

    • 문자{개수}
    • (문자열){개수}

    h{3}은 h가 3개 있는지 판단하고, (hello){3}은 hello가 3개 있는지 판단

    >>> 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'>

    휴대전화 번호 형식 판단하기(중요)

    특정 범위에서 문자(숫자)가 몇개 있는지 판단 

    • [0-9]{개수}
    >>> 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'>
    >>> re.match('[0-9]{3}-[0-9]{4}-[0-9]{4}', '010-1000-100')   # 숫자 3개-4개-4개 패턴에 매칭되지 않음

    이 기능으로 문자(숫자)의 개수 범위도 지정할 수 있다.

    • (문자){시작개수,끝개수} : 시작 개수 ~ 끝개수
    • (문자열){시작개수,끝개수} : 시작 ~ 끝  
    • [0-9]{시작개수,끝개수} : 시작 ~ 끝

     

     

    >>> 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'>
    >>> re.match('[0-9]{2,3}-[0-9]{3,4}-[0-9]{4}', '02-10-1000')  # 2~3개-3~4개-4개 패턴에 매칭되지 않음

    숫자와 영문 문자를 조합해서 판단하기

    지금까지 정규표현식으로 특정 문자 범위에 포함되는지를 확인하였다면

    이젠 특정 문자 범위에 포함되지 않는지 판단해보자

    아래와 같이 문자(숫자) 범위 앞에 ^를 붙이면 해당 범위를 제외한다.

    • [^범위]*
    • [^범위]+

    즉, '[^A-Z]+'는 대문자를 제외한 모든 문자(숫자)가 1개 이상 있는지 판단

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

    앞에서 사용하였던 특정 문자열로 시작히는지 판단할때도 ^ 를 사용했었다

    문법이 비슷해서 햇갈리기 쉬우니 주의하자.

    범위를 제외할때는 [^A-Z]+'와 같이 [ ] 안에 넣어주고,

    특정 문자 범위로 시작할 때는 '^[A-Z]+'와 같이 [ ] 앞에 붙여준다.

    아래과 같이 '^[A-Z]+'는 영문 대문자로 시작하는지 판단

    • ^[범위]*
    • ^[범위]+
    >>> re.search('^[A-Z]+', 'Hello')        # 대문자로 시작하므로 패턴에 매칭됨
    <_sre.SRE_Match object; span=(0, 1), match='H'>

    물론 특정 문자(숫자) 범위로 끝나는지 확인할 때는 정규표현식 뒤에 $를 붙이면 된다.

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

    특수문자 판단하기

    특수 문자를 판단할 때는 특수 문자 앞에 \를 붙이면 된다.

    단, [ ] 안에서는 \를 붙이지 않아도 되지만 에러가 발생하는 경우에는 \를 붙입니다

    • \특수문자
    >>> re.search('\*+', '1 ** 2')                    # *이 들어있는지 판단
    <_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, \D, \w, \W를 사용하면 편리

    • \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 또는 \S로 표현할 수도 있다

    • \s: [ \t\n\r\f\v]와 같음. 공백(스페이스), \t(탭) \n(새 줄, 라인 피드), \r(캐리지 리턴), \f(폼피드), \v(수직 탭)을 포함
    • \S: [^ \t\n\r\f\v]와 같음. 공백을 제외하고 \t, \n, \r, \f, \v만 포함
    >>> re.match('[a-zA-Z0-9 ]+', 'Hello 1234')     # ' '로 공백 표현
    <_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'>

    출처  : 코딩도장 갓

    dojang.io/mod/page/view.php?id=2436

     

    파이썬 코딩 도장: 43.2 범위 판단하기

    이번에는 문자열이 숫자로 되어있는지 판단해보겠습니다. 다음과 같이 [ ](대괄호) 안에 숫자 범위를 넣으며 * 또는 +를 붙입니다. 숫자 범위는 0-9처럼 표현하며 *는 문자(숫자)가 0개 이상 있는지

    dojang.io

     

    728x90
Designed by Tistory.