IT world

[Python] 24.01.18 기타 내용과 정규표현식 본문

모두의 연구소(오름캠프)/AI 모델 활용 백엔드 개발 과정

[Python] 24.01.18 기타 내용과 정규표현식

엄킹 2024. 1. 18. 17:47

우선 오전 강의의 시작은 파이썬의 버전별 변경사항을 간단하게 확인했다.

  • Python 3.5: async await
  • Python 3.6: Dict에 순서, f-string, 타입힌트
  • Python 3.7: dataclasses
  • Python 3.8: 왈러스 연산자(:=)
  • Python 3.9: 딕셔너리 결합 연산자(|)
  • Python 3.10: match

 

파일 입출력

파이썬의 파일 저장은 다양한 형태로 저장이 가능하다 (txt, csv, html 등) 

다양한 예제를 통해 파일의 입출력을 확인하였고, with open(_, _) as _ : 방식을 사용하는 것을 권장한다.

 

1. txt 파일 생성

[텍스트 파일 생성 예시]
[텍스트 파일 생성]

 

2. Excel 파일 생성

엑셀 파일을 생성한 후에 시트를 추가하고, 각 셀의 위치에 값을 작성했다.

[Excel 파일 생성 예시]

 

3. html 파일 읽어오기

[info.html 파일 읽기 예시]

 

비트 연산

비트(Bit)란 컴퓨터가 처리하는 데이터의 최소단위를 말하며 컴퓨터 내부 연산에는 2진수가 사용되며, 이에따라 비트는 0과 1로 구성된다. 비트 연산은 이진 연산을 하겠다는 의미와 같고 카카오 코딩 테스트 문제를 예시로 확인해보겠다.

 

* 비트 연산자의 연산의 전개 과정

  1. 10진수를 2진수로 변환
  2. 2진수에서 비트연산을 전개
  3. 결과값을 다시 10진수로 변환

* 연산자

  1. and(&) 연산자 : 두 비트열의 동일한 위치에 1이 있는 경우에만 1을 반환
  2. or(|) 연산자 : 두 비트열의 동일한 위치에 하나라도 1이 있는 경우 1을 반환
  3. xor(^) 연산자 : 두 비트열의 동일한 위치의 값이 다른 경우에만 1을 반환
  4. not(~) 연산자 : 비트열을 반전시킵니다. 1은 0으로, 0은 1로 변환
  5. shift 연산자 
    • 왼쪽 시프트 연산자(<<): 비트열을 왼쪽으로 이동시키며, 빈 자리는 0으로 채움
    • 오른쪽 시프트 연산자(>>): 비트열을 오른쪽으로 이동시키며, 빈 자리는 0으로 채

카카오 코딩테스트 문제로 예시를 작성해보겠다.

[출처] https://school.programmers.co.kr/learn/courses/30/lessons/17681

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

해당 문제는 2진법으로 풀어야하는 문제로, 출력결과는 #과 공백으로 출력하도록 되어있다.

매개변수
n 5
arr1 [9, 20, 28, 18, 11]
arr2 [30, 1, 21, 17, 28]
출력 ["#####","# # #", "### #", "# ##", "#####"]

 

위의 테이블을 보면 이진법으로 어떤 연산을 활용해야하는 유추할 수 있으며, or 연산을 통해 풀이를 작성하였다.

 

각 리스트 첫번째 원소인 9와 30을 예로 풀어보면,

더보기

1. 9의 이진수 = 1001 

2. 30의 이진수 = 11110

3. or(|) 연산은 각 위치에서 1이 하나라도 존재하면 1을 반환

4. 01001

    11110  [or 연산]

  -----------

    11111 → 연산 결과

 

따라서 정답 1의 값은 #으로 변경된 것을 확인할 수 있다.

[정답]

 

 

+ 추가로 f-string 문법 서식 지정자에 대한 설명을 해주셨다. 이런 내용은 검색해서 확인해보면 좋을 것 같다.

[f-string 서식 지정자 예시]

 

정규 표현식

정규 표현식이란 복잡한 문자열을 처리할 때 사용하는 기법으로, 특정한 규칙을 가진 문자열의 집합을 표현하는데 사용하는 형식의 언어이다. 

 

정규표현식은 구굴에서 연습사이트를 제공해주는데 해당 사이트에서 연습하면 좋다.

https://regexr.com/

 

RegExr: Learn, Build, & Test RegEx

RegExr is an online tool to learn, build, & test Regular Expressions (RegEx / RegExp).

regexr.com

 

그렇다면 정규 표현식은 왜 필요한가? 먼저 정규 표현식을 전혀 모른다고 가정하고 프로그램을 작성한다면

더보기

주민등록번호를 포함하고 있는 텍스트가 있다. 이 텍스트에 포함된 모든 주민등록번호의 뒷자리를 * 문자로 변경해보자

1. 전체 텍스트를 공백 문자로 나눈다(split)

2. 나뉜 단어가 주민등록번호 형식인지 조사한다.

3. 단어가 주민등록번호 형식이라면 뒷자리를 *로 변환한다.

4. 나뉜 단어를 다시 조립한다.

 

이렇게 각 순서에 맞는 확인이 필요한 코드로 구현이 될 것이고, 이는 코드가 길어지는 형태로 만들어 질 수 있다.

 

반면 정규 표현식을 사용한다면 훨씬 간편하고 직관적인 코드를 작성할 수 있다.

import re 

data = """
park 800905-1049118
"""

pat = re.compile("(\d{6})[-]\d{7}")
print(pat.sub("\g<1>-*******", data))

 

이렇게 정규 표현식을 사용하면 코드가 상당히 간결해진다. 만약 찾으려는 문자열 또는 바꾸어야 할 문자열의 규칙이 매우 복잡하다면 정규 표현식의 효율은 더욱 커진다.

 

메타 문자(Meta characters)

메타 문자란 문자가 가진 원래의 의미가 아닌 특별한 용도로 사용되는 문자를 말한다. 정규표현식에서 사용되는 메타 문자는 다음과 같다.

더보기

.   ^   $   *    +    ?    \    |    (    )    {    }    [    ]

정규 표현식에서 대괄화[] 는 대괄호 안에 포함된 문자들 중 하나와 매치를 뜻한다. (대괄호안의 텍스트 중 택 1)

(예시)
h[eay]llo # e,a,y 중 하나와 매치

'hello'
'hallo'
'hyllo' # 3개의 문자열 매치

'hqllo' # 매치되지 않음

 

대괄호 안의 두 문자에 -를 사용하면 두 문자 사이의 범위를 뜻한다

[a-c] # a와 C사이의 범위 = [abc]와 같음
[0-5] # 0~5 = [012345]와 같음
[a-zA-Z] # 모든 알파벳
[a-zA-Z0-9] # 모든 알파벳과 숫자

(예시)
# 1. 
h[a-zA-Z]llo -> h_llo 모든 문자를 매치

# 2.
010-[0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9] => 010-xxxx-xxxx 0~9까지 숫자를 찾음
010-[0-9]{4}-[0-9]{4} => 위의 코드를 더 간결하게 표현

 

자주쓰는 정규표현식

1. 처음과 끝

  • ^hello : 처음에 hello ↔ h[^e]llo : 해당 문자를 제외하고 찾을때 => 사용에 주의하자.
  • hello$ : 끝에 hello

2. 모든 문자

  • ./ : 모든 문자 호출

3. 수량자 : 해당 문자가 몇개 있는지를 명시하여 패턴을 찾는 방식

더보기

_* : 앞에 있는 문자가 0개 ~ N개
_+ : 앞에 있는 문자가 1개 ~ N개
_? : 앞에 있는 문자가 0개 ~ 1개

{3} : 3개
{3,} : 3개 이상
{1,3} : 1개 ~ 3개

_* : 앞에 있는 문자가 0개 ~ N개 ({0,})
_+ : 앞에 있는 문자가 1개 ~ N개({1,})
_? : 앞에 있는 문자가 0개 ~ 1개 ({0,1})

/[0-9]{3}[-.* ][0-9]{4}[-.* ][0-9]{4}/gm
/[0-9a-zA-Z]{2,3}[-.* ][0-9]{3,4}[-.* ][0-9]{4}/gm
/[0-9a-zA-Z]+@[0-9a-zA-Z]+.[a-zA-Z]+/gm

 

\d : 숫자[0-9]와 같다

\D : 비숫자, [^0-9]와 같다

\w : 숫자 + 문자, [a-zA-Z0-9]와 같다

\W : 숫자 + 문자가 아닌 것, [^a-zA-Z0-9]와 같다

\s :  공백 [ \t\n\r\f\v]와 같다

\S : 비공백 [^ \t\n\r\f\v]와 같다

\b : 단어 경계 (`\w`와 `\W`의 경계)

\B: 비단어 경계

findall()

정규식과 매치되는 모든 문자열을 리스트로 반환한다.

해당 예시도 카카오 코딩테스트 문제로 작성해보겠다. (스타상과 아차상 계산은 제외)

[출처] https://school.programmers.co.kr/learn/courses/30/lessons/17682

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

해당 문제는 총 3번의 다트를 던져 0~10의 정수와 문자 S, D, T, *, #로 구성된 문자열이 입력될 시 총점수를 반환하는 문제이다. 

 

[입력 예시]

dartResult answer 설명
1S2D3T 32 1 ** 1 + 2**2 + 3**3
1S2D10T 1005 1 ** 1 + 2**2 + 100**3

[정답]

 

정규 표현식 중 ([0-9]|10) 에서 점수가 10점이 들어왔을 경우 10이란 값을 1과 0으로 나눠지는 것을 방지하기 위해 10까지 확인하도록 설정했다.

 

sub()

정규식을 이용해 문자열을 치환하는 방법이다.

해당 예시도 카카오 코딩테스트 문제로 작성해보겠다.

[출처] https://school.programmers.co.kr/learn/courses/30/lessons/120849

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

해당 문제는 문자열에 영어의 모음을 제거한 문자열을 반환하도록 하는 문제이다.

 

[입력 예시]

변수 값 result
'bus' 'bs'
'nice to meet you' 'nc t mt y'

[정답]

 

정규 표현식 sub()을 사용하여 해당 매칭되는 문자열을 빈문자로 치환하였다. (대괄호안에 해당되는 문자를 전부 치환)

Comments