การค้นหาสตริงย่อยสุดท้ายที่เกิดขึ้นในสตริงแทนที่สิ่งนั้น


104

ดังนั้นฉันจึงมีรายการสตริงที่ยาวในรูปแบบเดียวกันและฉันต้องการค้นหาสตริงสุดท้าย "" อักขระในแต่ละตัวและแทนที่ด้วย ". -" ฉันได้ลองใช้ rfind แล้ว แต่ดูเหมือนจะใช้มันไม่ถูกต้องเพื่อทำสิ่งนี้


คำตอบ:


163

สิ่งนี้ควรทำ

old_string = "this is going to have a full stop. some written sstuff!"
k = old_string.rfind(".")
new_string = old_string[:k] + ". - " + old_string[k+1:]

1
ขอบคุณคนมาก จะต้องศึกษาว่าสักครู่ ... นี่คือการใช้ชิ้นส่วนใช่มั้ย?
Adam Magyar

@AdamMagyar ใช่คอนเทนเนอร์ [a: b] สไลซ์จากดัชนีสูงสุดถึง b-1 ของคอนเทนเนอร์ ถ้า 'a' ถูกละไว้ค่าเริ่มต้นจะเป็น 0; ถ้า 'b' ถูกละไว้ค่าเริ่มต้นคือ len (คอนเทนเนอร์) ตัวดำเนินการบวกจะเชื่อมต่อกัน ฟังก์ชั่น rfind ตามที่คุณชี้ให้เห็นจะส่งกลับดัชนีที่ควรดำเนินการแทนที่
Aditya Sihag

26

ในการแทนที่จากทางขวา:

def replace_right(source, target, replacement, replacements=None):
    return replacement.join(source.rsplit(target, replacements))

ใช้งานอยู่:

>>> replace_right("asd.asd.asd.", ".", ". -", 1)
'asd.asd.asd. -'

1
ฉันชอบโซลูชันนี้แน่นอน แต่การมีreplacements=Noneพารามิเตอร์ดูเหมือนจะเป็นข้อผิดพลาดสำหรับฉันเพราะหากละเว้นพารามิเตอร์ฟังก์ชันจะทำให้เกิดข้อผิดพลาด (ลองใน Python 2.7) ฉันขอแนะนำให้ลบค่าเริ่มต้นตั้งเป็น -1 (สำหรับการแทนที่ไม่ จำกัด ) หรือทำให้ดีกว่าreplacements=1(ซึ่งฉันคิดว่าควรเป็นพฤติกรรมเริ่มต้นสำหรับฟังก์ชันนี้โดยเฉพาะตามสิ่งที่ OP ต้องการ) ตามเอกสารพารามิเตอร์นี้เป็นทางเลือก แต่ต้องเป็น int หากกำหนด
ข้อสังเกต

เผื่อว่าใครอยากได้ซับเดียว: ". -".join("asd.asd.asd.".rsplit(".", 1)). สิ่งที่คุณทำคือการแยกสตริงจากด้านขวาสำหรับ 1 รายการและรวมสตริงอีกครั้งโดยใช้การแทนที่
bsplosion

14

ฉันจะใช้ regex:

import re
new_list = [re.sub(r"\.(?=[^.]*$)", r". - ", s) for s in old_list]

2
นี่เป็นคำตอบเดียวที่ใช้ได้หากไม่มีจุดเลย ฉันจะใช้วิธีมองว่า:\.(?=[^.]*$)
จอร์เจีย

6

ซับหนึ่งจะเป็น:

str=str[::-1].replace(".",".-",1)[::-1]


1
นี้เป็นธรรม คุณกำลังย้อนกลับสตริงแทนที่แล้วย้อนกลับ คุณกำลังทำ.replaceกับสตริงที่กลับด้าน ทั้งสองสายที่ผ่านไปreplaceจะต้องกลับกันด้วย มิฉะนั้นเมื่อคุณย้อนกลับสตริงเป็นครั้งที่สองตัวอักษรที่คุณเพิ่งใส่จะถอยหลัง คุณสามารถใช้สิ่งนี้ได้ก็ต่อเมื่อคุณแทนที่ตัวอักษรหนึ่งตัวด้วยตัวอักษรเดียวและถึงแม้ฉันจะไม่ใส่สิ่งนี้ในรหัสของคุณในกรณีที่มีคนเปลี่ยนรหัสนี้ในอนาคตและเริ่มสงสัยว่าทำไมถึงเขียนคำว่า sdrawkcab
Boris

1

คุณสามารถใช้ฟังก์ชันด้านล่างซึ่งจะแทนที่คำที่เกิดขึ้นครั้งแรกจากด้านขวา

def replace_from_right(text: str, original_text: str, new_text: str) -> str:
    """ Replace first occurrence of original_text by new_text. """
    return text[::-1].replace(original_text[::-1], new_text[::-1], 1)[::-1]

0
a = "A long string with a . in the middle ending with ."

# ถ้าคุณต้องการค้นหาดัชนีของการเกิดครั้งสุดท้ายของสตริงใด ๆ ในกรณีของเราเรา # จะพบดัชนีของการเกิดครั้งสุดท้ายด้วย

index = a.rfind("with") 

# ผลลัพธ์จะเป็น 44 เนื่องจากดัชนีเริ่มจาก 0


-1

วิธีไร้เดียงสา:

a = "A long string with a . in the middle ending with ."
fchar = '.'
rchar = '. -'
a[::-1].replace(fchar, rchar[::-1], 1)[::-1]

Out[2]: 'A long string with a . in the middle ending with . -'

คำตอบของ Aditya Sihag ด้วยคำตอบเดียวrfind:

pos = a.rfind('.')
a[:pos] + '. -' + a[pos+1:]

สิ่งนี้จะย้อนกลับสตริงแทนที่ด้วย นอกเหนือจากนั้นมันเป็นการทำซ้ำคำตอบของรูทและอย่างที่ฉันบอกว่าไม่มีประสิทธิภาพเลยทีเดียว
Gareth Latty

@ Lattyware คุณหมายถึงมันกลับด้านa?
อเล็กซ์แอล

ฉันหมายความว่ามันกลับด้าน'. -'ในเอาต์พุต
Gareth Latty

การคาดหวังให้ผู้ใช้ย้อนกลับสตริงตามตัวอักษรด้วยมือไม่ใช่ความคิดที่ดี แต่มีแนวโน้มที่จะผิดพลาดและไม่ชัดเจน
Gareth Latty

@ Lattyware เห็นด้วย ฉันทำให้มันหลากหลาย (ฉันรู้ว่ามันเป็นวิธีที่ไม่มีประสิทธิภาพและไม่เหมาะในทุกกรณี - ของคุณreplace_rightดีกว่ามาก)
Alex L
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.