首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 更多程式設計知識

Python 字串處理:rindex() 方法完整教學與右向索引搜尋

     編輯:更多程式設計知識

從字串右側搜尋子字串最後出現位置,並在找不到時拋出例外而非回傳 -1,這正是 rindex() 的設計用途。它與 rfind() 行為幾乎相同,唯一差異在錯誤處理策略。本文詳細說明語法、參數、例外處理、與 rfind/index 比較及實戰應用。

方法語法與說明

str.rindex(sub[, start[, end]])
  • sub:要搜尋的子字串。
  • start(選填):搜尋起始索引(含),預設 0。
  • end(選填):搜尋結束索引(不含),預設字串長度。
  • 回傳:子字串最後一次出現的索引(整數)。
  • 找不到行為:拋出 ValueError: substring not found。
  • 索引方向:同 rfind,索引從左向右計算(0 起始),僅回傳最右匹配位置。

實際程式碼範例

#!/usr/bin/python3
str1 = "this is string example....wow!!!"
str2 = "is"

# 範例 1:基本用法
print(str1.rindex(str2))   # 5(最後一個 "is")
print(str1.index(str2))    # 2(第一個 "is")

# 範例 2:指定範圍
print(str1.rindex(str2, 0, 10))  # 5
# print(str1.rindex(str2, 10, 0))  # ValueError(空範圍)

# 範例 3:找不到拋出例外
try:
    print(str1.rindex("xyz"))
except ValueError as e:
    print(f"找不到: {e}")  # 找不到: substring not found

# 範例 4:空字串特殊行為
print(str1.rindex(""))     # len(str1) = 35
print(str1.index(""))      # 0

四大搜尋方法完整對照

方法搜尋方向找到回傳找不到行為適用場景
find()左→右(首次)索引回傳 -1不確定存在、流程控制
rfind()右→左(末次)索引回傳 -1不確定存在、從右找
index()左→右(首次)索引拋 ValueError確定存在、視缺失為錯誤
rindex()右→左(末次)索引拋 ValueError確定存在、從右找

例外處理最佳實務

1. EAFP 風格(Python 慣用)


def find_last_occurrence(text, target):
    try:
        return text.rindex(target)
    except ValueError:
        return -1  # 或 None、拋出自訂例外

print(find_last_occurrence("abcabc", "b"))  # 4
print(find_last_occurrence("abcabc", "x"))  # -1

2. LBYL 風格(先檢查)


def find_last_occurrence_lbyl(text, target):
    if target in text:
        return text.rindex(target)
    return -1

# 注意:'in' 會掃描一次,rindex 再掃描一次,效能較差

3. 自訂例外與上下文


class SubstringNotFoundError(ValueError):
    def __init__(self, text, target, start=0, end=None):
        self.text = text
        self.target = target
        self.start = start
        self.end = end
        super().__init__(f"Substring '{target}' not found in text[{start}:{end}]")

def safe_rindex(text, target, start=0, end=None):
    try:
        return text.rindex(target, start, end)
    except ValueError:
        raise SubstringNotFoundError(text, target, start, end)

# 使用
try:
    pos = safe_rindex("hello world", "x")
except SubstringNotFoundError as e:
    print(f"錯誤: {e}, 文本長度: {len(e.text)}")

實務應用場景

1. 路徑解析(確定格式正確時)


def get_filename_and_ext(path):
    """假設 path 為合法路徑,必含檔名"""
    # 最後一個斜線
    slash_idx = path.rindex("/")
    filename = path[slash_idx + 1:]
    
    # 最後一個點(副檔名分隔)
    # 若無點,rindex 拋出例外 → 視為格式錯誤
    dot_idx = filename.rindex(".")
    name = filename[:dot_idx]
    ext = filename[dot_idx + 1:]
    return name, ext

# 正確
print(get_filename_and_ext("/home/user/file.txt"))  # ('file', 'txt')

# 錯誤:無副檔名
try:
    get_filename_and_ext("/home/user/README")
except ValueError:
    print("路徑缺少副檔名")

2. 協議解析(固定格式)


def parse_http_request_line(line):
    """解析 'GET /path HTTP/1.1'"""
    # 最後空格前為版本
    last_space = line.rindex(" ")
    version = line[last_space + 1:]
    
    # 第一空格後為路徑起始
    first_space = line.index(" ")
    method = line[:first_space]
    path = line[first_space + 1:last_space]
    
    return method, path, version

print(parse_http_request_line("GET /api/users HTTP/1.1"))
# ('GET', '/api/users', 'HTTP/1.1')

3. 結合切片的安全提取


def extract_between_last(s, left_delim, right_delim):
    """提取最後一對分隔符之間的內容"""
    try:
        left_idx = s.rindex(left_delim)
        right_idx = s.rindex(right_delim, left_idx + len(left_delim))
        return s[left_idx + len(left_delim):right_idx]
    except ValueError:
        return None

log = "[START] Task A [END] [START] Task B [END]"
print(extract_between_last(log, "[START] ", " [END]"))  # Task B

進階:正則版 rindex


import re

def rindex_regex(pattern, string, start=0, end=None):
    """正則搜尋最後匹配,找不到拋出 ValueError"""
    if end is None:
        end = len(string)
    matches = list(re.finditer(pattern, string[start:end]))
    if not matches:
        raise ValueError(f"Pattern '{pattern}' not found")
    last = matches[-1]
    return (last.start() + start, last.end() + start)

# 使用
try:
    print(rindex_regex(r"error_\d+", "error_1 error_2 error_3"))  # (16, 24)
except ValueError as e:
    print(e)

總結

rindex() 是「確定存在、從右找、缺失即錯誤」場景的標準工具。核心價值:**以例外明確表達「不應發生」的情況**,避免 -1 混入索引運算導致隱蔽 Bug。搭配 try/except(EAFP)或 in 檢查(LBYL)使用。路徑解析、協議分析、固定格式提取是典型應用。記住:索引仍從左計算,start/end 遵循切片語意支援負索引。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved