Skip to content
This page has been auto-translated and may contain errors.View in English

문자열

여러분이 작성하는 거의 모든 프로그램에 텍스트가 등장합니다. 이름, 메시지, 점수, 라벨 등이죠. 파이썬에서는 어떤 텍스트든 문자열이라고 부릅니다. 따옴표로 감싼 모든 값이 문자열이에요. 작은따옴표든 큰따옴표든 똑같이 동작합니다.

문자열은 파이썬의 주된 텍스트 타입입니다. 사용자명부터 URL 경로, 포맷된 출력까지 모든 것을 담아냅니다. 작은따옴표와 큰따옴표는 동일한 결과를 만들어내며, 선택은 스타일의 문제입니다.

str은 파이썬의 불변 유니코드 시퀀스 타입입니다. 터미널 I/O, 파일 내용, 네트워크 응답, 직렬화된 데이터 등 모든 시스템 경계에 자리잡고 있습니다. 두 따옴표 스타일은 동일한 객체를 만들어내며, 토크나이저는 이를 똑같이 취급합니다.

python
greeting = "Hello, world"
username = '민준'

따옴표 선택이 중요한 경우는 텍스트 안에 따옴표가 포함될 때뿐입니다. 이스케이프할 필요가 없도록 반대 스타일을 사용하세요:

커뮤니티 관례는 큰따옴표입니다. 실용적으로 스타일을 바꿀 이유는 콘텐츠에 해당 문자가 포함될 때 이스케이프를 피하기 위함입니다:

관례는 큰따옴표입니다. 스타일을 바꿀 유일한 이유는 콘텐츠에 그 구분자가 포함되어 있을 때 백슬래시 이스케이프를 피하기 위함입니다:

python
note    = "It's a great day"      # 안에 아포스트로피, 큰따옴표 사용
message = 'She said "hello"'      # 안에 큰따옴표, 작은따옴표 사용
escaped = "She said \"hello\""    # 또는 백슬래시로 이스케이프

불변성

문자열은 불변입니다: 한 번 만들면 바꿀 수 없습니다. 문자열은 만들어지는 순간 영구적으로 고정된다고 생각하세요. 문자열을 수정하는 것처럼 보이는 모든 연산은 실제로는 완전히 새로운 문자열을 만들어내는 것입니다. 원본은 그대로 유지됩니다.

문자열은 불변입니다: 어떤 메서드도 문자열을 제자리에서 수정하지 않습니다. 텍스트를 변환하는 모든 연산은 새 문자열을 반환하고 원본은 그대로 둡니다. 실용적인 결과는, 어딘가에 할당하지 않은 메서드 호출은 아무것에도 영향을 미치지 않는다는 점입니다.

str 객체는 불변입니다: 내부 버퍼는 생성 시 고정되며 쓰기가 불가능합니다. 이로 인해 문자열은 세 가지 유용한 특성을 가집니다: 해시 가능(딕셔너리 키와 집합 멤버로 유효), 복사 없이 참조 간 공유 안전, 그리고 짧은 리터럴에 대한 CPython 인터닝 최적화 대상이 될 수 있습니다.

python
name = "민준"
name = name.upper()   # "민준"은 변경되지 않고, 새 문자열이 만들어짐

직접적인 결과: 특정 위치의 문자를 바꿀 수 없습니다. 시도하면 파이썬이 오류를 발생시킵니다.

python
name = "alice"
name[0] = "A"   # TypeError: 'str' object does not support item assignment

수정된 문자열을 얻으려면 슬라이싱이나 메서드를 사용해 새 문자열을 만드세요. 둘 다 아래에서 다룹니다.

문자 할당을 시도하면 이 제약이 직접 드러납니다:

python
name = "alice"
name[0] = "A"   # TypeError: 'str' object does not support item assignment

수정된 버전이 필요할 때, 표준적인 도구는 위치 기반 편집을 위한 슬라이싱과 연결, 치환을 위한 replace()입니다. 둘 다 새 문자열을 만들어내며 원본은 그대로 둡니다.

str.__setitem__은 구현되어 있지 않으며, 아이템 할당은 무조건 TypeError를 발생시킵니다. 위치 기반 수정에는 슬라이싱을 사용하세요: name[:1].upper() + name[1:]. 치환에는 replace(). 여러 조각을 조립할 때는 "".join(parts)가 중요합니다: 루프 안에서 반복되는 s += chunk는 각 +가 결합된 길이의 새 버퍼를 할당하고 두 피연산자를 복사해 넣기 때문에 O(n²)입니다. join()은 한 번만 할당합니다.

인덱싱과 슬라이싱

문자열의 모든 문자는 0부터 시작하는 번호 매겨진 위치를 가집니다. 대괄호 안에 위치 번호를 넣어 개별 문자를 읽을 수 있습니다. 음수는 끝에서부터 거꾸로 셉니다.

문자열은 0부터 시작하는 인덱싱을 가진 시퀀스입니다. 음수 인덱스는 끝에서부터 셉니다. 슬라이싱은 단일 표현식으로 어떤 연속 범위든 추출하며, 범위를 벗어난 값에 대해서도 오류를 발생시키지 않습니다.

str은 전체 시퀀스 프로토콜을 구현합니다. 첨자 접근(s[i])은 정수와 함께 __getitem__을 거치며 범위를 벗어난 입력에 대해 IndexError를 발생시킵니다. 슬라이싱(s[start:stop:step])은 slice 객체를 전달하며, 인덱스는 유효한 범위로 조용히 클램핑되므로 슬라이스에서는 IndexError가 발생할 수 없습니다.

python
word = "Python"
#       012345

print(word[0])    # "P"
print(word[2])    # "t"
print(word[5])    # "n"
print(word[-1])   # "n"  (마지막 문자)
print(word[-2])   # "o"  (끝에서 두 번째)

-1은 항상 마지막 문자, -2는 끝에서 두 번째, 이런 식입니다. 문자열의 정확한 길이를 모를 때 끝부분을 원할 때 유용합니다.

음수 인덱스는 감쌉니다: -1len(s) - 1, -2len(s) - 2입니다. 길이를 수동으로 계산하지 않고 끝 기준으로 접근할 때 가장 유용합니다. 범위를 벗어난 음수 인덱스도 양수와 마찬가지로 여전히 IndexError를 발생시킵니다.

음수 인덱스는 경계 검사 전에 len(s) + i로 정규화됩니다. 인터프리터에는 특별한 케이스 처리가 없고, 단순한 산술입니다. 범위를 벗어나면 부호와 관계없이 IndexError가 발생합니다.

슬라이싱은 덩어리를 추출합니다. [start:stop]start를 포함하고 stop을 제외합니다:

python
word = "Python"

print(word[0:2])   # "Py"     (위치 0과 1)
print(word[2:])    # "thon"   (위치 2부터 끝까지)
print(word[:3])    # "Pyt"    (시작부터 위치 2까지)
print(word[:])     # "Python" (전체 문자열의 복사본)
print(word[::2])   # "Pto"    (두 문자마다 하나씩)
print(word[::-1])  # "nohtyP" (뒤집기)

가장 자주 사용하는 세 가지 패턴: 처음 n개 문자를 위한 word[:n], 위치 n부터 끝까지를 위한 word[n:], 마지막 n개 문자를 위한 word[-n:]. word[::-1]은 문자열을 뒤집습니다. 처음에는 이상해 보이지만, 이것은 관용적인 파이썬이며 자주 보게 될 것입니다.

직접 인덱싱과 달리, 슬라이싱은 IndexError를 발생시키지 않습니다. 파이썬은 범위를 벗어난 인덱스를 조용히 클램핑하므로, 짧은 문자열에 대한 word[100:]은 크래시 대신 ""를 반환합니다. step 인자는 보폭을 제어합니다: word[::2]는 한 문자 건너뛰면서 가져오고, word[::-1]은 역순으로 순회합니다.

s[start:stop:step]slice(start, stop, step)__getitem__에 전달합니다. 세 인자 모두 0이나 len()이 아니라 None을 기본값으로 가집니다. 음수 step의 경우 기본값이 뒤집힙니다: startlen - 1, stop-(len + 1)이 기본값입니다. 이것이 [::-1]이 명시적인 경계 없이 전체 문자열을 역방향으로 순회할 수 있게 하는 이유입니다.

필수 문자열 메서드

문자열에는 내장 메서드들이 함께 옵니다: 모든 문자열 값에서 직접 호출할 수 있는 연산들이죠. 문자열(또는 그 문자열을 담은 변수)을 쓰고, 점을 찍고, 메서드 이름을 씁니다. 각 메서드는 새 문자열을 반환합니다. 원본은 절대 변경되지 않습니다.

문자열 메서드는 str 타입에 부착된 함수입니다. 문자열은 불변이므로, 모든 메서드는 원본을 수정하는 대신 새 문자열을 반환합니다. 할당하거나 어딘가로 전달하지 않은 메서드 호출은 지속적인 효과가 없습니다.

str의 메서드는 타입 객체에 정의되어 있으며 C로 구현되어 있습니다. 모든 변환 메서드는 불변성 계약을 따릅니다: 새 str 객체를 반환합니다. CPython의 구현은 전체적으로 유니코드를 인식하며, 메서드는 바이트가 아닌 코드 포인트 단위로 동작합니다.

대소문자

python
text = "Hello, World"

text.lower()       # "hello, world"
text.upper()       # "HELLO, WORLD"
text.title()       # "Hello, World"  (각 단어 대문자화)
text.capitalize()  # "Hello, world"  (첫 단어만)

lower()upper()가 가장 자주 사용할 두 가지입니다. lower()는 특히 텍스트를 비교할 때 유용합니다: 양쪽에 .lower()를 호출하면 "Alice""alice"는 같은 것이 됩니다.

lower()는 비교나 저장 전 표준 정규화 단계입니다. title()은 각 단어의 첫 글자를 대문자화하는데, 단순한 규칙을 사용하므로 축약형에서 오작동합니다: "it's""It'S"가 됩니다. 표시 전용 포맷팅으로만 취급하세요.

lower()는 유니코드 풀 케이스 변환을 적용합니다. 대소문자 구분 없는 비교에는 casefold()가 더 정확합니다: lower()가 건너뛰는 추가 변환(예: 독일어 ß가 ss로 변환)을 적용합니다. title()은 영숫자가 아닌 모든 문자 뒤에 대문자화를 적용하므로 축약형과 하이픈으로 연결된 이름을 잘못 처리합니다. 올바른 타이틀 케이싱을 위해서는 로직을 수동으로 구현하세요.

공백

python
text = "  hello  "

text.strip()    # "hello"    (양쪽)
text.lstrip()   # "hello  "  (왼쪽만)
text.rstrip()   # "  hello"  (오른쪽만)

strip()은 문자열의 양 끝에서 공백을 제거합니다. 사용자 입력이나 파일에서 가져온 텍스트를 다룰 때 거의 항상 사용하게 됩니다. 떠도는 공백은 조용한 실패를 일으키기 때문이죠: "alice" != "alice ".

strip()은 모든 선행 및 후행 공백(공백, 탭, 줄바꿈)을 제거합니다. 방향별 변형은 한쪽만 정리할 수 있게 해주며, 들여쓰기를 건드리지 않고 후행 줄바꿈을 제거할 때 유용합니다. 세 메서드 모두 특정 문자를 대신 제거할 수 있도록 선택적인 문자 인자를 받습니다.

인자 없는 strip()str.isspace()True를 반환하는 문자를 제거하며, 이는 비ASCII 공백을 포함하는 유니코드 인식 집합입니다. 문자 인자와 함께 사용하면 양 끝에서 해당 집합의 어떤 문자든 제거합니다(접두사 매칭이 아닌 문자 멤버십 검사). "xxhelloxx".strip("x")"hello"를 반환합니다. 다중 문자 인자는 그 문자들 중 어떤 것이든 개별적으로 제거하며, 이는 미묘한 버그의 흔한 원천입니다.

찾기

python
text = "Hello, world"

text.find("world")         # 7
text.find("Python")        # -1  (찾지 못함)
text.count("l")            # 3
text.startswith("Hello")   # True
text.endswith("world")     # True

find()는 문자열 안에서 특정 텍스트 조각이 시작되는 위치를 반환합니다. 거기에 없으면 -1을 반환합니다. 문자열이 특정 무언가로 시작하거나 끝나는지만 신경 쓸 때는 startswith()endswith()를 사용하세요.

find()는 첫 번째 매치의 시작 인덱스 또는 -1을 반환합니다. -1 관례 덕분에 검사 없이 결과를 슬라이싱이나 산술에 직접 사용할 수 있습니다. startswith()endswith()는 각각 문자열 튜플을 받을 수 있어 한 번의 호출로 여러 접두사나 접미사를 테스트할 수 있습니다.

find()는 왼쪽에서 오른쪽으로 가는 선형 스캔이며, 최악의 경우 O(n*m)입니다. index()는 동일하지만 매치가 없으면 ValueError를 발생시킵니다: 부재가 프로그래밍 오류일 때는 index(), 예상되는 입력일 때는 find()를 사용하세요. startswith()endswith()는 첫 불일치에서 단락되며 접두사/접미사 테스트에 대해 find()in 검사보다 빠릅니다.

치환

python
text = "Hello, world"

text.replace("world", "Python")   # "Hello, Python"
text.replace("l", "L")            # "HeLLo, worLd"  (모든 등장)
text.replace("l", "L", 1)         # "HeLlo, world"  (첫 번째만)

replace()는 한 텍스트 조각의 모든 등장을 다른 것으로 교체하고 새 문자열을 돌려줍니다. 원본은 변경되지 않습니다. 첫 번째 등장만 교체하고 싶다면 세 번째 인자를 전달하세요.

replace()는 기본적으로 겹치지 않는 모든 등장을 교체합니다. count 인자는 몇 개가 교체될지 제한합니다. 새 문자열을 반환하므로 호출을 연결할 수 있습니다: text.replace("a", "A").replace("e", "E")는 두 치환을 순차적으로 적용합니다.

replace()는 리터럴 부분 문자열 스캔을 수행하며, count가 주어지지 않으면 단일 할당으로 결과를 만듭니다. count가 있으면 일찍 멈춥니다. 패턴 기반 치환에는 파이썬의 re 모듈이 적절한 도구입니다. 이는 모듈 챕터에서 다룹니다.

분할과 결합

split()은 구분자에서 문자열을 조각으로 자르고 리스트로 반환합니다. 무엇으로 자를지 알려주면 됩니다:

split()은 구분자에서 분할하고 세그먼트를 리스트로 반환합니다. 인자 없이 호출하면 모든 공백 연속에 대해 분할하고 여러 연속 공백으로 인한 빈 문자열을 버립니다:

split(sep)은 왼쪽에서 오른쪽으로 스캔하며, sep의 겹치지 않는 모든 등장에서 분할합니다. 인자가 없으면 다른 알고리즘을 사용합니다: 모든 공백 연속에 대해 분할하고 결과에서 선행 및 후행 공백을 제거합니다. rsplit(sep, n)은 오른쪽에서 분할하며, 점으로 구분된 경로나 네임스페이스 식별자의 마지막 세그먼트를 분리할 때 유용합니다:

python
csv_row = "민준,28,서울"
parts = csv_row.split(",")     # ["민준", "28", "서울"]

"  hello   world  ".split()   # ["hello", "world"]

리스트가 뭔가요?

리스트는 순서가 있는 값들의 모음입니다. 위의 ["민준", "28", "서울"]이 하나의 리스트입니다. 리스트는 자체적인 챕터를 갖고 있습니다; 지금은 split()이 생성하고 join()이 소비하는 아이템들의 시퀀스로 취급하세요.

join()은 그 반대를 합니다: 문자열 리스트를 하나로 결합합니다. .join() 앞의 문자열은 각 항목 사이에 놓입니다:

python
words = ["Hello", "world"]

" ".join(words)    # "Hello world"
", ".join(words)   # "Hello, world"
"".join(words)     # "Helloworld"

기억해야 할 패턴: separator.join(list_of_strings). 구분자는 왼쪽에, 리스트는 오른쪽에. " ".join(words)는 각 단어 사이에 공백을 넣습니다. "".join(words)는 사이에 아무것도 없이 붙입니다.

join()은 여러 조각으로부터 단일 문자열을 조립할 때 적절한 도구입니다. 각 단계에서 새 문자열을 만드는 대신 단일 할당을 수행합니다. 두세 개 문자열에는 +로도 충분합니다. 어떤 의미 있는 크기의 리스트가 생기면 join()을 사용하세요.

join()은 O(n)입니다: __iter__를 한 번 호출하고, 필요한 전체 길이를 한 번에 계산하고, 단일 할당을 수행한 다음, 각 조각과 구분자를 직접 버퍼에 씁니다. 반복되는 +는 O(n²)입니다: 각 연산이 결합된 길이의 새 버퍼를 할당하고 두 피연산자를 복사해 넣습니다. CPython은 단일 지역 변수에 대한 반복적인 +=에 제한적인 최적화를 갖고 있지만, 리팩토링에 취약하고 보장되지 않습니다. join()은 항상 정확하고 항상 빠릅니다.

f-문자열

f-문자열은 값을 텍스트 안에 직접 임베드합니다. 여는 따옴표 앞에 f를 넣고, 변수나 표현식을 중괄호로 감싸세요. 코드가 실행될 때 파이썬이 채워 넣습니다. 값 뒤에 콜론을 추가해 표시 방법을 제어할 수도 있습니다.

f-문자열은 {} 안의 모든 표현식을 런타임에 평가하고 결과를 문자열로 변환합니다. 중괄호 안의 콜론은 포맷 명세를 도입합니다: 소수점 자리수, 정렬, 숫자 포맷팅을 제어하기 위한 간결한 구문입니다.

f-문자열(PEP 498)은 각 {} 표현식을 format(value, spec)을 호출하는 바이트코드로 컴파일하며, 이는 value.__format__(spec)에 위임됩니다. __format__을 구현하는 모든 클래스는 f-문자열 안에서 자체 표시를 제어합니다. 변환 플래그 !r, !s, !a는 포맷 호출 전에 repr(), str(), 또는 ascii()를 적용합니다.

python
name  = "민준"
score = 94.5

print(f"Hello, {name}!")           # "Hello, 민준!"
print(f"Score: {score:.1f}%")      # "Score: 94.5%"
print(f"2 + 2 = {2 + 2}")          # "2 + 2 = 4"
print(f"Name: {name.upper()}")     # "Name: 민준"

: 뒤의 포맷 명세는 값이 어떻게 표시될지 제어합니다:

명세의미예시
.2f소수점 2자리f"{3.14159:.2f}""3.14"
.0%퍼센트, 소수점 없음f"{0.94:.0%}""94%"
,천 단위 구분자f"{1000000:,}""1,000,000"
>1010자 내 우측 정렬f"{'hi':>10}"" hi"

.2f를 가장 많이 사용하게 됩니다: 소수를 표시할 때마다 긴 숫자 행렬 대신 깔끔한 숫자를 원할 때입니다. 표의 나머지는 필요할 때 거기에 있습니다. {} 안에 어떤 변수, 산술, 메서드 호출이든 넣을 수 있습니다.

.2f.0%가 대부분의 표시 포맷팅을 다룹니다. 정렬 지정자(>, <, ^)는 너비와 결합되면 표 형태의 출력을 만듭니다. 일반 패턴은 {value:[align][width][.precision][type]}입니다. 일단 구성 요소를 인식하면 모든 조합을 외우지 않고도 어떤 명세든 읽을 수 있습니다.

명세는 __format__에 그대로 전달되며, 내장 타입은 이를 C에서 처리합니다. !r은 가장 유용한 변환 플래그입니다: 포맷팅 전에 repr()을 호출하여 문자열 주위에 따옴표를 추가하고 보이지 않는 문자(탭, 후행 공백, 줄바꿈)를 이스케이프 시퀀스로 가시화합니다. 사용자 정의 클래스는 임의의 명세 문자열을 받아 어떤 출력이든 생성하도록 __format__을 구현할 수 있습니다.

여러 줄 문자열

한 줄 이상에 걸친 문자열을 작성하려면 삼중 따옴표를 사용하세요: 시작에 " 세 개, 끝에 세 개. 파이썬은 작성한 그대로 모든 줄바꿈과 간격을 보존합니다.

삼중 따옴표 문자열은 모든 공백과 줄바꿈을 그대로 보존합니다. 이메일 템플릿과 SQL 쿼리 같은 긴 텍스트 블록의 표준이며, 독스트링에도 사용됩니다: 함수나 클래스 본문 시작 부분에 놓인 인라인 문서입니다.

삼중 따옴표 리터럴은 각 줄의 선행 공백을 포함하여 모든 문자를 그대로 보존합니다. 함수, 클래스 또는 모듈 본문의 첫 번째 문장으로 사용될 때, 파이썬은 해당 객체의 __doc__ 속성으로 문자열을 저장합니다. help() 같은 도구가 이를 표시하며, 선행 공백은 일반적으로 textwrap.dedent()에 의해 제거됩니다. 삼중 '''"""는 동등하며, """가 관례입니다.

python
message = """
민준님께,

주문해 주셔서 감사합니다.

감사합니다,
The Team
"""

이스케이프 시퀀스

어떤 문자들은 문자열 안에 직접 입력하기 어렵습니다. 파이썬은 이스케이프 시퀀스를 사용합니다: 무언가를 나타내는 백슬래시 뒤의 글자입니다. 자주 사용할 두 가지는 새 줄을 위한 \n과 탭을 위한 \t입니다.

이스케이프 시퀀스는 문법을 깨뜨리거나 직접 입력할 수 없는 문자를 임베드할 수 있게 해줍니다. 자주 사용할 것들: \n(줄바꿈), \t(탭), \\(리터럴 백슬래시), \"\'(매칭 구분자 문자열 안의 따옴표). 윈도우 경로는 백슬래시가 필요한데, 이는 이스케이프 처리와 충돌합니다. 비활성화하려면 r을 접두사로 붙이세요.

파이썬은 C 스타일 이스케이프 세트에 더해 유니코드 이스케이프를 지원합니다: \uXXXX(16비트 코드 포인트), \UXXXXXXXX(32비트), \xNN(16진수 바이트 값), \N{name}(명명된 유니코드 문자). 원시 문자열 리터럴(r"...")은 모든 이스케이프 처리를 억제하여 모든 백슬래시를 그대로 문자열에 전달합니다. 이는 백슬래시가 파이썬의 토크나이저가 아닌 소비자에게 의미를 전달하는 윈도우 경로와 정규 표현식에 필수적입니다.

시퀀스문자
\n줄바꿈
\t
\\리터럴 백슬래시
\"큰따옴표
\'작은따옴표
python
print("Line one\nLine two")        # 두 줄의 출력
print("Name:\tAlice")              # Name:   Alice
path = r"C:\Users\Alice\Documents" # 원시 문자열, 이스케이프 처리 없음

문자열 내용 검사

파이썬에는 문자열이 무엇을 포함하는지에 대한 예/아니요 질문에 답하는 메서드가 있습니다. True 또는 False를 반환합니다. 초기에 가장 유용한 것: isdigit()은 변환 전에 문자열이 모두 숫자인지 확인하게 해주어 예상치 못한 입력에서의 크래시를 피할 수 있게 합니다.

is* 메서드는 각각 전체 문자열의 특정 속성을 테스트하며, 모든 문자가 조건을 만족할 때만 True를 반환합니다. 주된 용도는 입력 검증입니다: 변환 전에 검사하여 예상치 못한 입력에서의 크래시를 피하는 것이죠. int() 전의 isdigit()이 고전적인 패턴입니다.

is* 메서드는 ASCII 범위가 아닌 유니코드 카테고리 검사를 사용합니다. isdigit()0-9를 넘어선 위첨자 숫자와 기타 숫자 유니코드 코드 포인트에 대해 True를 반환합니다. 엄격한 ASCII 숫자 검사를 위해서는 s.isascii() and s.isdigit()를 결합하세요. isnumeric()은 더 광범위하여 분수와 숫자 값 유니코드 문자를 포함합니다. 사용하기 전에 실제로 필요한 것이 무엇인지 알아두세요.

python
"42".isdigit()       # True
"hello".isalpha()    # True
"hello42".isalnum()  # True
"   ".isspace()      # True
"Hello".islower()    # False
"HELLO".isupper()    # True

실전에서

공백을 제거하고, 대소문자를 정규화한 다음, 필요한 것을 꺼내세요. 이 순서는 거의 모든 사용자 제공 텍스트를 처리합니다:

python
raw_input = "  [email protected]  "
email     = raw_input.strip().lower()   # "[email protected]"

at_pos   = email.find("@")
username = email[:at_pos]
domain   = email[at_pos + 1:]

print(f"User:   {username}")    # "minjun"
print(f"Domain: {domain}")      # "example.com"

부분에서 URL을 만들고 즉시 검증 및 파싱하기:

python
BASE_URL = "https://api.example.com"
version  = "v2"
resource = "users"
user_id  = 42

url      = f"{BASE_URL}/{version}/{resource}/{user_id}"
# "https://api.example.com/v2/users/42"

protocol = url.split("://")[0]                    # "https"
secured  = url.startswith("https")
domain   = url.split("://")[1].split("/")[0]      # "api.example.com"

print(f"Protocol : {protocol}")
print(f"Secure   : {secured}")
print(f"Domain   : {domain}")

find(), 슬라이싱, 그리고 f-문자열 정렬을 사용하여 구조화된 로그 라인 파싱하기:

python
log_entry = "[2024-01-15 09:42:11] ERROR: File not found: report.csv"

timestamp = log_entry[1:20]
rest      = log_entry[22:]                # "ERROR: File not found: report.csv"
colon_pos = rest.find(":")
level     = rest[:colon_pos]              # "ERROR"
message   = rest[colon_pos + 2:]          # "File not found: report.csv"

print(f"[{timestamp}] {level:>8}: {message}")
# [2024-01-15 09:42:11]    ERROR: File not found: report.csv

find()는 경계를 찾고, 슬라이싱은 부분을 추출하며, >8 포맷 명세는 심각도 레이블을 우측 정렬하여 레벨 이름의 길이가 다르더라도 열이 일관되게 유지되도록 합니다.

메서드 참조

메서드하는 일
.lower() / .upper()모두 소문자 / 모두 대문자로 변환
.title() / .capitalize()각 단어 대문자화 / 첫 단어만
.strip() / .lstrip() / .rstrip()둘러싼 공백 제거
.find(sub)첫 매치의 인덱스, 또는 -1
.count(sub)sub가 몇 번 나타나는지
.startswith(s) / .endswith(s)접두사 / 접미사 검사
.replace(old, new)등장 교체
.split(sep)리스트로 분할
sep.join(iterable)항목을 문자열로 결합
.isdigit() / .isalpha() / .isalnum()문자 타입 검사