Learning Objectives
- 使用 Python 文字資料型態(str):引號、跳脫字元、三引號
- 成員運算子(Membership Operators)in、not in
- 文字資料型態的索引(index)與切片(slice)
- 文字資料型態相關運算與方法(methods)
為什麼要學字串
姓名、電子郵件、一篇心得、一個檔案的內容,都是文字。在 Python 裡,文字的型態叫做字串(str)。
處理文字是寫程式最常做的事之一:檢查信箱格式、把資料用逗號切開、去掉多餘的空白、把「Java」全部換成「Python」。
字串有兩個一定要記住的特性:
| 特性 | 意思 | 結果 |
|---|---|---|
| 有順序(sequence) | 每個字元都有位置編號 | 可以用索引 s[0]、切片 s[1:4] 取出一部分 |
| 不可變(immutable) | 建立之後內容不能改 | 所有「修改」都是做出新的字串 |
在 Python 3,所有字串都以 Unicode 存放,中文、日文、表情符號都可以直接放在字串裡。
引號與跳脫字元
單引號 '...' 和雙引號 "..." 完全相同,看字串內容方便用哪一個。第 10 行之後是跳脫字元:反斜線 \ 加上一個字元,代表一個特殊字元。注意輸出區 \t 和 \n 印出來的樣子。
常用的跳脫字元
| 寫法 | 意思 |
|---|---|
\n |
換行(Linefeed) |
\t |
Tab(水平定位) |
\\ |
反斜線本身 |
\'、\" |
單引號、雙引號 |
\r |
歸位(Carriage Return) |
\xhh |
十六進位 hh 代表的字元,例如 \x41 是 A |
投影片的
'c:\weblog2.txt'雖然印得出來(\w不是跳脫字元,所以被原樣保留),但 Python 3.12 會發出警告。 寫 Windows 路徑請用'c:\\weblog.txt'或r'c:\weblog.txt'。
三引號:多行字串
用三個雙引號 """ 或三個單引號 ''' 括起來的字串可以跨越多行,換行會被保留下來。看右邊 poem 的值裡面藏著一個 \n。
字串不可變
第 6 行想把第一個字元換成 J,Python 會丟出 TypeError。這裡用 try / except 把錯誤接住、印出訊息,讓程式繼續跑(例外處理在 Module 17 會詳細介紹)。真的要「改」,就是用切片和 + 做出一個新的字串,再讓 var1 指向它。
索引與切片
以 s = 'Python' 為例,每個字元有兩種編號:
| 字元 | P | y | t | h | o | n |
|---|---|---|---|---|---|---|
| 正索引 | 0 | 1 | 2 | 3 | 4 | 5 |
| 負索引 | -6 | -5 | -4 | -3 | -2 | -1 |
- 索引
s[i]取出一個字元;超出範圍會出現IndexError。 - 切片
s[start:stop:step]取出一段:從start開始、不包含stop、每次跳step個。 三個都可以省略:start預設開頭、stop預設結尾、step預設 1。切片超出範圍不會出錯,只會切到邊界為止。
索引與切片實戰
這是投影片 Demo 的 'Python Basics'(13 個字元,中間的空白也算一個)。每一行先自己猜答案,再按「下一步」對照輸出。
想一想:索引、切片與不可變
下面的程式會印出什麼?
s = "Python"
print(s[1:4])
下面的程式會印出什麼?
s = "Python"
print(s[-2:], s[::2])
下面的程式執行後會怎樣?
s = "cat"
s[0] = "b"
print(s)
成員運算子 in / not in
x in y:x 有沒有出現在 y 裡面。用在字串時,可以檢查一個字元或一整段子字串;用在串列、元組、集合時,檢查某個元素在不在裡面。
字串的運算與方法
假設 a = 'Hello'、b = 'Python':
| 運算 | 說明 | 結果 |
|---|---|---|
a + b |
連接 | 'HelloPython' |
a * 2 |
重複 | 'HelloHello' |
'H' in a |
成員運算 | True |
len(a) |
長度 | 5 |
str(45) |
轉成字串 | '45' |
字串也有很多方法(method),寫法是 字串.方法()。因為字串不可變,這些方法都是傳回新的字串,原本的字串不會變:
| 方法 | 作用 |
|---|---|
s.upper() / s.lower() |
轉成大寫/小寫 |
s.isalpha() / s.isdigit() / s.isalnum() / s.isspace() |
是否全是字母/數字/字母或數字/空白 |
s.split(sep) |
用 sep 切成串列;不給 sep 就用空白切 |
s.strip(chars) / s.lstrip() / s.rstrip() |
去掉兩邊/左邊/右邊的指定字元(預設空白) |
s.find(sub) |
sub 第一次出現的位置,找不到傳回 -1 |
s.replace(old, new) |
把 old 全部換成 new |
常用字串方法
注意第 5 行:呼叫了好幾個方法之後,s3 本身還是原來的樣子。想保留結果,要把傳回值指派給一個名稱(像第 11 行的 parts)。
想一想:運算、in 與方法
下面的程式會印出什麼?
print("##ab##".strip("#"), len("a\tb"))
下面的程式會印出什麼?
print("na" * 2 + "B" in "nanaBa")
下面的程式會印出什麼?
print("a,b,,c".split(","))
下面的程式會印出什麼?
s = "hi"
s.upper()
print(s)
實作:整理電子郵件
使用者輸入的信箱前後多了空白、大小寫也不一致。請完成三個 TODO:去掉前後空白並轉成小寫、用 @ 切開成帳號與網域,最後檢查網域是不是以 .edu.tw 結尾的學校信箱(用 in 檢查即可)。
重點精華回顧
- 字串的特性:單引號與雙引號相同;三引號可以寫多行;反斜線開頭的是跳脫字元,
r'...'原始字串不跳脫。 - 字串有順序、不可變:不能
s[0] = 'x',所有修改都是做出新的字串。 - 成員運算子
in、not in檢查字元、子字串或元素是否出現,適用於字串、串列、元組、集合。 - 索引與切片:索引從 0 開始、負索引從 -1 倒數;
s[start:stop:step]不包含stop。 - 字串方法:
upper、lower、isalpha、isdigit、split、strip、find、replace都傳回新值,記得指派給名稱才會保留。