Python3從頭/尾刪除子符串的正確操作


一、說明

從某個時候發現python的字符串變量自帶的strip()方法,除了可以刪除字符串頭尾的空格,還可以用來刪除頭尾的字符串覺得很好用。也就一直這么用,一直也沒發現什么問題。

今天在修復一個bug時使用了strip()方法但從結果看bug並沒有按預期被消除,一是沒懷疑strip()刪除子字符串有什么問題,二是程個代碼比較長,三是依賴的下層庫並不太可靠,排查了大半天最后才知道是對strip()用途理解錯所致,算是吃了大虧。

 

二、錯誤的刪除子字符串操作示例

2.1 錯誤的strip()操作

假設我們有以下一個字符串,我們通過rstrip()刪除其尾部的“str”子串沒有問題,但通過rstrip()刪除其尾部的“_str”子串時卻出現問題。

# 示例字符串
test_str = "this_is_a_test_str"

# 期望刪除尾部的“str”,結果與預期相符
# 預期是“this_is_a_test_”,結果也是“this_is_a_test_”
test_str.rstrip("str")

# 期望刪除尾部的“_str”,結果與預期不相符。
# 預期是“this_is_a_test”,實際是“this_is_a_te”
test_str.rstrip("_str")

 

2.2 strip()原理說明

之所以會出現出現上邊這種不符合預期的情況,是因為strip()根本不是用來刪除“給定的字符串”的,而是用來刪除給定的字符集直到遇到不在字符集中的字符為止。

在test_str.rstrip("str")中,字符集是”s“、”t“、”r“三個字符,字符串按rstrip()指示從右向左開始查找字符進行刪除,當刪除完”str“后遇到了”_“,而”_“不在字符集中所以刪除就停止了,所以得到的結果是”this_is_a_test_“;和刪除”str“字符串結果相一致,但這只是一種巧合。

在test_str.rstrip("_str")時,字符集是”_“、”s“、”t“、”r“四個字符,字符串按rstrip()指示從右向左開始查找字符進行刪除,當刪除完”_str“后接下來的”t“和”s“仍都在字符集中所以仍被刪除,所以得到的結果是”this_is_a_te“,而不是”this_is_a_test“。

 

2.3 一個典型的字符串截取錯誤【可跳過】

# 示例字符串
test_str = "this_is_a_test_str"

# 以下操作期望能去截去頭部的this和尾部的str
# 期忘得到“is_a_test”,實際結果是“a_test_str”
test_str.lstrip("this_")[:test_str.rindex("_")]

左邊為什么"is_"也被刪了在上一小節已經說清楚了,那為什么右邊的"_str"沒有被刪除呢,這是因為lstrip()並不修改原先的test_str而是返回一個新的字符串,而test_str.rindex("_")定位到的仍是原先”this_is_a_test_str“的”_“的位置而不是新返回來”a_test_str“的”_“的位置。

 

三、正確的刪除子字符串操作

有些地方說可以使用字符串自帶的replace()方法,但replace()會將所有匹配都進行替換這很粗糙,我們更多時候是想刪掉明確位置的字符串。

3.1 使用len()

# 示例字符串
test_str = "this_is_a_test_str"

# 期望得到“this_is_a_test”,實際結果也是“this_is_a_test”
test_str[:-len("_str")]

 

3.2 使用re.sub()

import re

# 示例字符串
test_str = "this_is_a_test_str"

# 期望得到“this_is_a_test”,實際結果也是“this_is_a_test”
re.sub("_str$","",test_str)

 

參考:

https://stackoverflow.com/a/1038845

https://www.geeksforgeeks.org/python-remove-the-given-substring-from-end-of-string/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM