프로그래밍 언어/Python

[Python] 문자열 다루기

eunnys 2023. 10. 29. 19:31

1. 문자열

문자열의 특징

  • 파이썬3은 Unicode 지원한다.
  • 문자열은 immutable한 데이터이다.
  • '문자열', "문자열", '''문자열''', """문자열"""
  • Single quotation('''), double quotation(""")을 3개씩 문장의 앞 뒤로 감싸면 여러 줄로 구성된 문자열을 만들 수 있다.

 

 

문자열 관련 연산자 : + *

  • 문자열 연결 : + (문자열과 숫자 연결 불가)
  • 문자열 반복 : *

 

 

Escape Sequence

- 문자 앞에 \을 붙여 언어에서 정의되어 있는 원래의 의미를 벗어나는 문자들을 말한다.

 

이스케이프 시퀀스 의미
\\ 역 슬래시 ( \ )
\' 작은따옴표 ( ' )
\" 큰따옴표 ( " )
\a ASCII 벨 (BEL)
\b ASCII 백스페이스 (BS)
\f ASCII 폼 피드 (FF)
\n ASCII 라인 피드 (LF)
\r ASCII 캐리지 리턴 (CR)
\t ASCII 가로 탭(TAB)

 

 

문자열 분리

  • 문자열을 구성하는 개별 문자를 읽을 때는 [] 괄호와 문자의 위치인 첨자를 적는다.
  • 문자열의 길이는 len() 함수를 통해 얻는다.

 

 

문자열 추출(슬라이싱)

  • 파이썬 문자열은 자바의 배열처럼 동작한다.
  • 음수 사용 가능

 

표현 의미
[ : ] 처음부터 끝까지
[start:] start offset부터 끝까지
[:end] 처음부터 end-1까지
[start:end] start offset부터 end-1까지
[start:end:step] step만큼 문자를 건너뛰면서, start offset부터
(end-1) offset까지 시퀀스를 추출

 

mystr = '학교종이 떙떙땡'
print(mystr)
print(mystr[0])
print(mystr[-1])
# mystr[1] = '원' # 문자열 값은 변경 불가능
mystr = '''동해물과 백두산이 마르고 닳도록
하느님이 보우하사 우리나라 만세
무궁화 삼천리 화려강산
대한사람 대한으로 길이 보전하세'''
print(mystr) # 여러 줄로 출력
hello = 'I say "hello" to you'
print(hello)

hello2 = "I say \"Hello\" to you"
print(hello2)

print('철수\t영희') # 한 탭 떨어져서 출력
print('철수\n영희') # 줄 바꿈

 

 

 

[문제] 파일 이름 슬라이싱
- 파일 이름: 20231018-123920.jpg

 

[출력 결과]
촬영 날짜: 2023년 10월 18일
촬영 시간: 12시 39분
확장자: jpg

file = '20231018-123920.jpg'
print(f'촬영 날짜: {file[:4]}년 {file[4:6]}월 {file[6:8]}일')
print(f'촬영 시간: {file[9:11]}시 {file[11:13]}분')
print(f'확장자: {file[-3:]}')

 

## 슬라이싱을 이용해 문자열 뒤집기 ##

# 문자열 뒤집기
str = 'hello' # olleh 출력
print(str[::-1])

 

 

문자열 관련 함수

 

함수명 설명
capitalize() 첫 번째 단어를 대문자로
lower() 모든 글자를 소문자로
title() 모든 단어의 첫 글자를 대문자로
upper() 모든 글자를 대문자로
swapcase() 대문자는 소문자로, 소문자는 대문자로
count(문자열) 해당 문자열이 몇 개 있는지
len(문자열) 문자열의 길이
endswith(문자열) 지정된 문자열로 끝나는지 여부 (True, False)
startswith(문자열) 지정된 문자열로 시작하는지 여부 (True, False)
find(문자열) 지정된 문자열의 오프셋 값 리턴
format() 출력 시 포멧을 지정
함수명 설명
구분문자.join(리스트) 문자열의 리스트를 하나의 문자열로 결합
replace(원본문자열, 바꿀문자열 [, 바꿀횟수]) 문자열을 지정한 문자열로 바꿈
rfind(문자열) 지정 문자열을 오른쪽에서 찾아서 출력
center(숫자) 문자열을 지정한 공간에서 중에 배치
ljust(숫자) 문자열을 지정한 공간에서 왼쪽에 배치
rjust(숫자) 문자열을 지정한 공간에서 오른쪽에 배치
split(구분자) 구분자를 기준으로 하나의 문자열을 리스트로 나눔
구분자 없이 사용하면 기본 구준자(공백, 줄나눔, 탭)를 사용
str(데이터) 괄호 안의 모든 데이터를 문자열로
strip(문자열) 문자열의 맨 앞과 맨 뒤에 지정 문자열을 삭제
rstrip(문자열) 문자열의 맨 뒤에 Whiye Space 삭제할 때 주로 사용
lstrip(문자열) 문자열의 맨 앞에 White Space 삭제할 때 주로 사용

 

s = '''생각이란 생각할수록 생각나므로
생각하지 말아야 할 생각은 생각하지 않으려고 하는 생각이
옳은 생각이라고 생각합니다.'''
print(s.count('생각'))  # string객체가 갖고있는 고유의 함수
print(len(s))  # 내장함수
s = 'Python programming'
print('a' in s)  # 집합형 데이터 안에 포함되었는지
print('z' in s)
s = '짜장 짬뽕 탕수육'
print(s.split()) # 구분자 공백, 리스트 형태로 반환

s2 = '서울->대전->대구->부산'
print(s2.split('->'))
city_list = ['서울', '대전', '대구', '부산']
ciity_string = ','.join(city_list)
print(ciity_string)
s = '대한민국' # 대-한-민-국
print('-'.join(s))

 

 

2. 문자열 대입

코드 설명
%s 문자열 (String)
%c 문자 1개 (Character)
%d 정수 (Integer)
%f 부동 소수 (Floating-point)
%o 8진수
%x 16진수
%% Literal % (문자 % 자체)

 

 

문자열 자리배치

 

%[-]폭[,유효자리수]서식

 

- 별도의 폭 지정이 없으면 변수의 자리수 만큼 차지하지만 폭을 지정하면 최소 지정된 만큼 폭을 확보한다.

- 실수는 폭 지정 외에 . 기호와 함께 실수 부분의 유효자리수를 지정할 수 있다.

- 유효자리수 지정이 없으면 소수점 이하 6자리까지 반올림하여 표시한다.

print('I eat %d apples'%3) # 정수
print('I eat %s apples'%'five') # 문자
print('I eat %d%% apples'%95) # %기호 포함
month = 8
day = 15
anni = '광복절'
print('%d월 %d일은 %s이다.'%(month, day, anni))

 

 

포맷팅

  • 문자열 내에 {} 괄호를 입력하고 format 함수의 인수로 삽입할 변수 또는 값을 입력하면 {}괄호 자리에 차례대로 인수 값이 전달된다.
  • {} 괄호 안에 0부터 시작하는 순서 값을 지정할 수도 있다.
num = 4
day = '삼'
s = '나는 사과 {}개를 먹고 {}일동안 아팠다.'.format(num, day)
print(s)
num = 4
day = '삼'
s = '나는 사과 {1}개를 먹고 {0}일동안 아팠다.'.format(num, day)
print(s)
s = '나는 사과 {num}개를 먹고 {day}일동안 아팠다.'.format(day=7, num=3)
print(s)

 

 

 

[문제] 주민등록번호 분석하기
- 임의의 주민등록번호를 입력받아 다음과 같이 생년과 성별을 추출하는 프로그램을 작성하세요.
- (입력) 881231-1234567 --> (출력) 88년생 남자

jumin = input('주민등록번호: ')
year = jumin[0:2]
sex = jumin[7]
s_gender = ''
if sex in ['1','3']:
    s_gender = '남자'
elif sex in ['2', '4']:
    s_gender = '여자'
else:
    s_gender = '성별오류'
print('%s년생 %s'%(year, s_gender))

 

 

 

[문제] 단어 수 세기
- 문자열 내 전체 단어가 몇개인가?
- 문자열 내 like 단어가 몇개인가?
- 문자열 내 가장 많이 나오는 단어는 무엇안가?
    > 1) 문자열 내에 줄바꿈(\n)문자를 공백 문자로 치환한다. replace(old string, new string)
    > 2) 모든 단어를 소문자로 변경한다. lower()문자열을 단어로 나눈다. split()
    > 3) 문자열을 단어로 나눈다. split()
    > 4) 최빈 단어를 찾을 때 사용하는 count()함수는 split()을 통해 단어 단위로 분할된 리스트에 대해 사용한다.

song = '''Hello, it's me 
I was wondering if after all these years you'd like to meet
To go over everything
They say that time's supposed to heal ya
But I ain't done much healing
Hello, can you hear me?
I'm in California dreaming about who we used to be
When we were younger and free
I've forgotten how it felt before the world fell at our feet
There's such a difference between us
And a million miles
Hello from the other side
I must've called a thousand times
To tell you I'm sorry for everything that I've done
But when I call, you never seem to be home
Hello from the outside
At least I can say that I've tried
To tell you I'm sorry for breaking your heart
But it don't matter, it clearly doesn't tear you apart anymore
Hello, how are you?
It's so typical of me to talk about myself, I'm sorry
I hope that you're well
Did you ever make it out of that town where nothing ever happened?
It's no secret that the both of us are running out of time
So hello from the other side (Other side)
I must've called a thousand times (Thousand times)
To tell you I'm sorry for everything that I've done
But when I call, you never seem to be home
Hello from the outside (Outside)
At least I can say that I've tried (I've tried)
To tell you I'm sorry for breaking your heart
But it don't matter, it clearly doesn't tear you apart anymore
Ooh-ooh, anymore
Ooh-ooh-ooh, anymore
Ooh-ooh, anymore
Anymore
Hello from the other side (Other side)
I must've called a thousand times (Thousand times)
To tell you I'm sorry for everything that I've done
But when I call, you never seem to be home
Hello from the outside (Outside)
At least I can say that I've tried (I've tried)
To tell you I'm sorry for breaking your heart
But it don't matter, it clearly doesn't tear you apart anymore'''

song = song.replace('\n', ' ').lower()  # 연속되는 처리로 쓸 수도 있음
print('like 단어의 갯수: ', song.count('like'))
word_list = song.split()
print('전체 단어 갯수: ', len(word_list))  # len()함수는 집합형 데이터의 원소의 갯수를 구하기도 함

# 가장 많이 나온 단어 찾기
max_count = 0 # 가장 많이 나온 단어의 횟수
max_word = '' # 가장 많이 나온 단어
for word in word_list:
    count = word_list.count(word) # 현재 단어의 포함 횟수 확인
    if count > max_count:
        max_count = count
        max_word = word
print('가장 많이 나온 단어는 %s이며 횟수는 %d이다.'%(max_word, max_count))

 

 

 

[문제] 영화예매 프로그램
- 10개 좌석만 있는 극장의 예매 프로그램 만들기
  (좌석 정보는 list로 선언)
- 비어있는 좌석은 0으로 표기하고, 예매가 된 좌석은 1로 표기한다.
- 만약 예약되어있는 좌석을 예약하려고 했을 때 적절한 오류 메세지를 출력하고 해당 좌석에 대해 다시 예약을 받는다.

    [예시]
    좌석을 예약하시겠습니까? (예약:1, 종료:0) 1
    현재의 예약 상태는 다음과 같습니다.
    ---------------------
    1 2 3 4 5 6 7 8 9 10
    ---------------------
    0 0 0 0 0 0 0 0 0 0
    몇번째 좌석을 예약하시겠습니까? 2
    예약되었습니다.

    좌석을 예약하시겠습니까? (예약:1, 종료:0) 1
    현재의 예약 상태는 다음과 같습니다.
    ---------------------
    1 2 3 4 5 6 7 8 9 10
    ---------------------
    0 1 0 0 0 0 0 0 0 0

seats = [0,0,0,0,0,0,0,0,0,0]  # 안에 있으면 계속 초기화되기 때문에 while문 밖에 있어야 함
while True:
    isContinue = input('좌석을 예약하시겠습니까? (예약:1, 종료:0) ') # 계산이 아니기에 int() 형변환 X
    if isContinue == '0':
        break
    elif isContinue == '1':
        print('현재의 예약 상태는 다음과 같습니다.')
        print('---------------------')
        print('1 2 3 4 5 6 7 8 9 10')
        print('---------------------')
        for s in seats:
            print('%2d'%s, end='')  # 2자리의 폭을 유지하며 옆으로 쭉 출력
        print() # 한 줄 띄기 위한 용도
        while True:
            seatNo = int(input('몇번째 좌석을 예약하시겠습니까? '))
            if seats[seatNo-1] == 1:  # seats 리스트의 방 번호는 0부터 시작하기에 -1해줌
                print('해당 좌석은 이미 예약되었습니다.')
            else:
                seats[seatNo-1] = 1  # 0을 1로 대입
                print('예약되었습니다.')
                break