跳到內容

字串 String

字串就是一段文字。前面已經一直在用它,這一章專門看字串能做哪些事:拆開、拼接、搜尋,以及把它排得整整齊齊。

字串裡的每個字都有索引,可以像串列一樣用索引和切片來取。len() 算的是有幾個字:

word = "Python"
print(word[0])
print(word[-1])
print(word[0:3])
print(len(word))

切片一樣可以用第三個數字當間隔。[::-1] 就是把字串反過來,是很常見的小技巧:

word = "Python"
print(word[::-1])

字串內建很多好用的方法,這裡是幾個最常見的:

text = " Hello, World "
print(text.upper())
print(text.strip())
print(text.replace("World", "Python"))
  • upper() / lower():全部轉大寫/小寫。
  • strip():去掉頭尾的空白。
  • replace(舊, 新):把字串裡的某段換成別的。

這幾個方法有個共通點:都是回傳一個新的字串,原本的字串不會被改到(字串和元組一樣,建立後不能直接修改)。

split() 依你指定的符號把字串切成一個串列;join() 相反,把串列裡的字串用某個符號串成一整段:

sentence = "蘋果,香蕉,橘子"
fruits = sentence.split(",")
print(fruits)
joined = "".join(fruits)
print(joined)

處理一行用逗號隔開的資料時,這兩個方法幾乎天天用到。

想知道某段文字在不在、在哪裡、出現幾次:

email = "user@example.com"
print("@" in email)
print(email.find("@"))
print(email.count("e"))
  • x in 字串:檢查有沒有,回傳 TrueFalse
  • find(x):回傳第一次出現的索引(找不到會回傳 -1)。
  • count(x):數出現幾次。

有一組方法用來檢查字串「是不是某種樣子」,回傳 TrueFalse,常用在檢查使用者輸入(例如密碼、帳號):

print("abc123".isalnum())
print("12345".isdigit())
print("Hello".isupper())
print("HELLO".isupper())
print("hello world".title())
  • isdigit():是不是全部都是數字。
  • isalnum():是不是全部都是文字或數字(沒有符號、空白)。
  • isupper() / islower():是不是全大寫/全小寫。
  • title():把每個單字的字首轉大寫。

rjust() 把字串靠右、補到指定寬度,第二個參數是拿什麼來補(預設是空白)。zfill() 則專門在左邊補 0,常用來排數字:

print("7".rjust(3))
print("7".rjust(3, "0"))
print("42".zfill(5))

每個字元在電腦裡都對應一個數字編號,Python 用的是 Unicode。這套編碼收錄了世界上各種文字,英文和數字的部分沿用更早的 ASCII,所以大寫 A 是 65;中文字也有自己的編號, 是 20013。ord() 把字元轉成它的編號,chr() 反過來把編號轉回字元:

print(ord("A"))
print(chr(65))
print(ord(""))
print(chr(ord("a") + 1))

chr(ord("a") + 1) 先拿到 a 的編號、加 1、再轉回字元,就得到 b。處理「下一個字母」這類問題時會用到。

想把變數的值嵌進一段文字,直覺的做法是用 + 把字串接起來。但 Python 的文字不能直接和數字相加,"你今年 " + age 會直接出錯,得先用 str() 把數字轉成字串,而且片段一多,引號和加號排起來也很難讀。f-string 就是來解決這件事的(Python 3.6 以後才有):在字串前面加一個 f,把變數用大括號 {} 包起來放進字串,值會自動帶進去,型別轉換也不用煩惱。下面兩行印出同一句話,比較看看哪個好讀:

name = "小美"
age = 20
print("你好," + name + ",你今年 " + str(age) + " 歲。")
print(f"你好,{name},你今年 {age} 歲。")

在大括號裡,變數後面加冒號還能指定格式,最常用的是控制小數位數:

price = 1234.5678
print(f"{price:.2f}")
print(f"{price:,.2f}")

:.2f 是「保留兩位小數」,:,.2f 再加上千分位逗號,很適合印金額。

在冒號後面放方向和寬度,可以把文字補到固定的寬度:< 靠左、> 靠右、^ 置中,後面的數字是欄寬,表示這一格總共佔幾個字元,內容不夠長就用空白補滿。三個名字長短不一,補滿之後直行就對齊了:

a = "Ann"
b = "Bob"
c = "Cathy"
print(f"|{a:<8}|{a:>8}|{a:^8}|")
print(f"|{b:<8}|{b:>8}|{b:^8}|")
print(f"|{c:<8}|{c:>8}|{c:^8}|")

(這裡用英文示範,因為欄寬算的是「字元數」,而中文字比英文寬,中英混排時對齊會有點跑掉。)

數字格式和對齊也能同時用,但擺放順序是固定的:先寫對齊和欄寬,再千分位,最後小數位數,像 {total:>12,.2f}。冒號後面其實是一整段「格式規格」,Python 按位置一段一段解讀,擺錯(例如 {total:.2f>12})會直接出錯:

price = 1234.5
total = 98765.432
print(f"|{price:>12,.2f}|")
print(f"|{total:>12,.2f}|")

格式規格還有更多花樣(補 0、帶正負號、百分比……),需要時可以查官方文件的格式規格說明

你在別人的程式裡可能會看到另外兩種比較舊的格式化寫法,%.format()

name = "小明"
age = 18
print("%s 今年 %d" % (name, age))
print("{} 今年 {}".format(name, age))

三種寫法做的事一樣。知道它們長什麼樣就好,自己寫的時候,用 f-string 通常最直覺、最好讀。

v0.4.0 (148a67b)