HOWTO · Python
在 Python 字串中查詢字元的所有索引
我們可以使用正規表示式、yield 關鍵字和列表推導式在 Python 中查詢字串中某個字元的所有索引。
本頁內容
在 Python 字串中尋找某個字元的所有出現位置,可以搭配 enumerate() 與條件判斷,收集符合條件的索引。Python 的索引從 0 開始,因此第一個字元的索引是 0。以下範例使用字串 "This is a string",並搜尋小寫的 "i"。
使用 enumerate() 與列表推導式找出字元的所有索引
給定一個字串和目標字元,這個列表推導式會依序傳回所有符合條件的索引。請執行以下範例:
本節中的程式碼以及顯示的標籤或輸出仍為英文。
string = "This is a string"
char = "i"
indices = [index for index, character in enumerate(string) if character == char]
print(indices)
enumerate(string) 會為每個字元提供一組值:該字元的索引與字元值。條件判斷只有在字元值等於 char 時才保留索引,而列表推導式會將這些索引收集成新的清單。以範例輸入來說,符合的位置是 2、5 和 13。比對有區分大小寫:搜尋 "I" 不會找到小寫的 "i"。如果目標字元沒有出現,結果會是 []。如果呼叫端一次需要所有索引,這通常是最清楚的做法。
使用 yield 延遲產生符合條件的索引
如果需要逐一處理結果,或輸入資料很大,產生器會很有用。下方函式採用與列表推導式相同的比較方式和順序,但會在迭代過程中遇到符合條件的索引時逐一產生。
本節中的程式碼以及顯示的標籤或輸出仍為英文。
def find_indexes(string, char):
for index, character in enumerate(string):
if character == char:
yield index
string = "This is a string"
char = "i"
indices = list(find_indexes(string, char))
print(indices)
呼叫 find_indexes(string, char) 會建立產生器;只有在要求值時,函式本體才會執行。你可以使用 for 迴圈逐一處理索引;若需要完整清單,則可將呼叫包在 list(...) 中。將產生器的結果轉成清單後,會得到與列表推導式相同的索引。如果沒有符合項目,迭代不會產生任何值,而 list(...) 的結果會是 []。yield 關鍵字會在將值交給呼叫端時暫停函式,並在下一次迭代時繼續執行。
使用正規表示式找出字元的所有索引
本文的三種方法都要求 char 是只包含一個字元的 Python 字串。採用相同的輸入條件,能讓逐字元比較和正規表示式範例保持一致。如果搜尋條件適合用正規表示式模式描述,請使用 re.finditer()。每個比對物件都能透過 start() 提供起始位置。如果目標是作為資料傳入的字面字元,請先用 re.escape() 處理;否則,.、* 或 [ 等字元可能會被解讀為正規表示式語法,而不是依字面內容搜尋。
本節中的程式碼以及顯示的標籤或輸出仍為英文。
import re
string = "This is a string"
char = "i"
pattern = re.escape(char)
indices = [match.start() for match in re.finditer(pattern, string)]
print(indices)
[2, 5, 13]
搜尋字面目標時,跳脫字元很重要,尤其是目標可能包含正規表示式中具有特殊意義的字元。如果你有意使用模式,請直接將模式傳給 re.finditer(),不要跳脫。若只要搜尋單一字面字元,enumerate() 更簡單;當比對規則需要模式功能時,正規表示式才最有用。這三種方法都會由左至右掃描、保留重複的比對結果,並傳回從 0 開始的位置。