[Py] - 정규표현식

Imomo·2021년 3월 24일
0

코테 - 파이썬

목록 보기
2/9

정규표현식

패턴

  • [ ] : 문자 클래스

  • Dot(.) : \n을 제외한 모든 문자와 매치 (점 하나는 글자 하나를 의미)

  • * : 0회 이상 반복 (업어도 상관 없음)

  • + 1회 이상 반복 (무조건 한번 이상 등장해야 함)

  • {m, n} m회 이상 n회 이하

  • l or 조건식을 의미

  • ^ 문자열의 시작 의미

  • $ 문자열의 끝을 의미

  • ? 0회 이상 1회 이하

  • \ 이스케이프, 또는 메타 문자를 일반 문자로 인식하게 한다

  • ( ) 그룹핑, 추출할 패턴을 지정한다.

  • [a-zA-Z] : 알파벳 모두

  • [0-9] 숫자를 포함한 문자열

  • [^0-9] 숫자를 제외한 문자열

정규식을 이용한 문장열 검색

  • match() - 문자열의 처음부터 정규식과 매치되는지 조사한다.
  • search() - 문자열 전체를 검색하여 정규식과 매치되는지 조사한다.
  • findall() - 정규식과 매치되는 모든 문자열(substring)을 리스트로 돌려준다.
  • finditer() - 정규식과 매치되는 모든 문자열(substring)을 반복 가능한 객체로 돌려준다.

findall 예제

import re
id1 = "...!@BaT#*..y.abcdefghijklm"
p = re.compile("[^a-zA-Z0-9-_.]") : # 정규표현식 패턴을 객체로 만듦
m = p.findall(id1)

출력결과

['!', '@', '#', '*']

[^] 특정 문자 범위에 포함되지 않는지 확인

  • 범위 앞에 ^를 붙이면 해당 범위를 제외
    [^A-Z]+ : 대문자를 제외한 모든 문자(숫자)가 1개 이상 있는지 판단합니다.

$ 특정 문자(숫자) 범위로 끝나는지 확인

  • 정규표현식 뒤에 $를 붙이면 됩니다.
    re.search('[0-9]+$', 'Hello1234') : 숫자로 끝나므로 패턴에 매칭됨

{} 문자 개수 확인

  • 문자{개수} , (문자열){개수}
    re.match('h{3}', 'hhhello') :h{3}은 h가 3개 있는지 확인
    re.match('(hello){3}', 'hellohellohelloworld') :(hello){3}은 hello가 3개 있는지 확인

Dot(.) 문자 사이 특정문자 확인

  • "a + 모든문자 + b"

    a.b

  • 예제
    aab - 맞음
    a0b - 맞음
    abc - 틀림

* 문자반복 확인

  • 바로앞 문자가 0번~무한반복 가능

    ca*t

  • 예제
    cat - 맞음
    ct - 맞음
    caaat - 맞음

re.sub

  • re.sub('패턴', '바꿀문자열', '문자열', 바꿀횟수)

예제

re.sub('apple|orange', 'fruit', 'apple box orange tree')
apple 또는 orange를 fruit로 바꿈
'fruit box fruit tree'

re.sub('[0-9]+', 'n', '1 2 Fizz 4 Buzz Fizz 7 8')
숫자만 찾아서 n으로 바꿈
'n n Fizz n Buzz Fizz n n'

sub - 교체함수

  • sub 함수는 바꿀 문자열 대신 교체 함수를 지정할 수도 있습니다. 교체 함수는 매개변수로 매치 객체를 받으며 바꿀 결과를 문자열로 반환하면 됩니다. 다음은 문자열에서 숫자를 찾은 뒤 숫자를 10배로 만듭니다.
def multiple10(m):        # 매개변수로 매치 객체를 받음
    n = int(m.group())    # 매칭된 문자열을 가져와서 정수로 변환
    return str(n * 10)    # 숫자에 10을 곱한 뒤 문자열로 변환해서 반환

re.sub('[0-9]+', multiple10, '1 2 Fizz 4 Buzz Fizz 7 8')
각숫자의 10을 곱한 결과값
'10 20 Fizz 40 Buzz Fizz 70 80'

카카오문제 (신규아이디추천) 예제

문제링크

다른방식

  • new_id에서 마침표(.)가 2번 이상 연속된 부분을 하나의 마침표(.)로 치환합니다.

    str = re.sub('\.+', '.', str)

       while '..' in answer: 
            answer = answer.replace('..', '.')
  • new_id에서 마침표(.)가 처음이나 끝에 위치한다면 제거합니다.

    st = re.sub('^[.]|[.]$', '', st)

코드 - 내가푼방법

import re
def check(c_id):    
    if c_id[0] == ".":
         c_id = c_id[1:]
    elif c_id[len(c_id)-1] == ".":
         c_id = c_id[0:len(c_id)-1] 
    return c_id
def solution(new_id):
    answer = '' 
    new_id = new_id.lower()  
    p = re.compile("[a-zA-Z0-9-_.]")
    m = p.findall(new_id)   
    while m:
        first = m.pop(0)  
        if first == ".":
            if answer != '':
                if answer[len(answer)-1] == first:
                    continue
            answer += first
        else:
            answer += first  
    answer = check(answer) # 처음 마지막. 체크 하기
    if answer == '':
        answer = "a"  
    if len(answer) > 15:
        answer = answer[:15]
    answer = check(answer) # 처음 마지막. 체크 하기
    while len(answer) < 3: 
            answer += answer[len(answer)-1] 
    print("m:", answer)  
    return answer

코드 - 다른사람 1

import re
def solution(new_id):
    st = new_id
    # 1
    st = st.lower()  	
    # 2
    st = re.sub('[^a-z0-9\-_.]', '', st)	
    # 3
    st = re.sub('\.+', '.', st)
    # 4
    st = re.sub('^[.]|[.]$', '', st)
    # 5
    st = 'a' if len(st) == 0 else st[:15] 
    st = re.sub('^[.]|[.]$', '', st)
    st = st if len(st) > 2 else st + "".join([st[-1] for i in range(3-len(st))])
    return st

코드 - 다른사람 2

def solution(new_id):
    answer = ''
    # 1
    new_id = new_id.lower()
    # 2
    for c in new_id:
        if c.isalpha() or c.isdigit() or c in ['-', '_', '.']:
            answer += c
    # 3
    while '..' in answer:
        answer = answer.replace('..', '.')
    # 4
    if answer[0] == '.':
        answer = answer[1:] if len(answer) > 1 else '.'
    if answer[-1] == '.':
        answer = answer[:-1]
    # 5
    if answer == '':
        answer = 'a'
    # 6
    if len(answer) > 15:
        answer = answer[:15]
        if answer[-1] == '.':
            answer = answer[:-1]
    # 7
    while len(answer) < 3:
        answer += answer[-1]
    return answer

0개의 댓글