วิธีการลบตัวละครทั้งหมดหลังจากตัวละครเฉพาะในงูหลาม?


148

ฉันมีสาย ฉันจะลบข้อความทั้งหมดหลังจากตัวละครบางตัวได้อย่างไร ( ในกรณีนี้... )
ข้อความหลังจากนั้นจะ...เปลี่ยนดังนั้นฉันจึงเป็นเหตุผลที่ฉันต้องการลบตัวละครทั้งหมดหลังจากที่หนึ่ง


6
หากคุณไม่แน่ใจว่าเหมาะสมแล้วโปรดอัปเดตคำถามของคุณเพื่อให้ตัวอย่างเฉพาะของสิ่งที่คุณต้องการทำ
S.Lott

คำตอบ:


259

แยกบนตัวแยกของคุณมากที่สุดและใช้ชิ้นแรก:

sep = '...'
rest = text.split(sep, 1)[0]

คุณไม่ได้พูดว่าจะเกิดอะไรขึ้นหากไม่มีตัวคั่น ทั้งวิธีนี้และโซลูชันของ Alex จะคืนค่าสตริงทั้งหมดในกรณีนั้น


คำขอคือ "ลบข้อความทั้งหมดหลังจาก" ตัวคั่นไม่ใช่ "รับ" ข้อความนั้นดังนั้นฉันคิดว่าคุณต้องการ [0] ไม่ใช่ [-1] ในการแก้ปัญหาที่ยอดเยี่ยมของคุณ
Alex Martelli

ทำงานได้อย่างสมบูรณ์แบบขอบคุณเพราะฉันแน่ใจว่า Ayman & Alex ทำเช่นกันดังนั้นขอบคุณทุกคน
Solihull

5
ใช้ rsplit () หากคุณต้องการแยกโดยอักขระที่เริ่มต้นจากจุดสิ้นสุดของสตริง
ซามูเอล

rsplit () ตอบคำถามจริง ๆ หากมีตัวคั่นหลายรายการเกิดขึ้น
เนท

94

สมมติว่าตัวคั่นของคุณคือ '... ' แต่อาจเป็นสตริงใดก็ได้

text = 'some string... this part will be removed.'
head, sep, tail = text.partition('...')

>>> print head
some string

หากไม่พบตัวคั่นheadจะประกอบด้วยสตริงเดิมทั้งหมด

มีการเพิ่มฟังก์ชันพาร์ติชันใน Python 2.5

partition (... ) S.partition (sep) -> (head, sep, tail)

Searches for the separator sep in S, and returns the part before it,
the separator itself, and the part after it.  If the separator is not
found, returns S and two empty strings.

อีกหนึ่งทางออกที่ดี - ที่เราละเมิด TOOOWTDI -?) อาจจะคุ้มค่าการทำงาน timeit เพื่อตรวจสอบ ...
อเล็กซ์เทล

9
.partition ชนะ - 0.756 usec ต่อ loop, vs 1.13 สำหรับ. split (การจัดรูปแบบความคิดเห็นไม่ให้ฉันแสดงการทดสอบที่แน่นอน แต่ฉันใช้ข้อความและตัวคั่น @ Ayman) - ดังนั้น +1 คำตอบของ @ Ayman !
Alex Martelli

1
และ btw สำหรับความสมบูรณ์โซลูชัน RE-based คือ 2.54 usec เช่นช้ากว่า @ Ayman หรือ @ Ned's อย่างใดอย่างหนึ่ง
Alex Martelli

พาร์ติชั่นชนะถ้าคุณอยู่ในดินแดน 2.5) สำหรับพวกเรา suckers ที่ติดอยู่ใน 2.4 เราต้องอยู่กับความเชื่องช้าของการแบ่งน้ำแข็ง
Gregg Lind

ตัวอย่างมีประโยชน์จริง ๆ
Md. Sabbir Ahmed

18

หากคุณต้องการลบทุกอย่างหลังจากการเกิดขึ้นครั้งสุดท้ายของตัวแยกในสตริงฉันพบว่าทำงานได้ดี:

<separator>.join(string_to_split.split(<separator>)[:-1])

ตัวอย่างเช่นหาก string_to_splitเป็นเส้นทางที่ต้องการroot/location/child/too_far.exeและคุณต้องการเส้นทางโฟลเดอร์เท่านั้นคุณสามารถแยกตาม"/".join(string_to_split.split("/")[:-1])และคุณจะได้รับ root/location/child


1
นอกจากนี้คุณสามารถเปลี่ยน -1 เป็นดัชนีใด ๆ ที่จะเกิดขึ้นที่คุณวางข้อความ
theannouncer

10

ไม่มี RE (ซึ่งฉันถือว่าเป็นสิ่งที่คุณต้องการ):

def remafterellipsis(text):
  where_ellipsis = text.find('...')
  if where_ellipsis == -1:
    return text
  return text[:where_ellipsis + 3]

หรือด้วย RE:

import re

def remwithre(text, there=re.compile(re.escape('...')+'.*')):
  return there.sub('', text)

อาจต้องการใช้ sep = '... ' เป็น kwarg และใช้ len (sep) แทนการเข้ารหัสแบบฮาร์ดทั้ง 3 เพื่อให้มันพิสูจน์ได้ในอนาคตมากขึ้นเล็กน้อย
cdleary

ใช่ แต่คุณต้องคอมไพล์ RE ในการโทรแต่ละครั้งดังนั้นประสิทธิภาพจึงทนสำหรับโซลูชัน RE (ไม่มีความแตกต่างที่แท้จริงสำหรับโซลูชันที่ไม่ใช่ RE) บางสิ่งบางอย่างไม่เสียค่าใช้จ่ายบางอย่างไม่ ... ;-)
Alex Martelli

@Alex - ขอบคุณสำหรับการทดสอบโซลูชัน!
Ayman Hourieh

2

เมธอด find จะส่งคืนตำแหน่งอักขระในสตริง จากนั้นถ้าคุณต้องการลบทุกสิ่งออกจากตัวละครทำสิ่งนี้:

mystring = "123⋯567"
mystring[ 0 : mystring.index("⋯")]

>> '123'

หากคุณต้องการเก็บตัวละครไว้ให้เพิ่ม 1 ไปยังตำแหน่งตัวละคร




0

อีกวิธีที่ง่ายต่อการใช้อีกครั้งจะเป็น

import re, clr

text = 'some string... this part will be removed.'

text= re.search(r'(\A.*)\.\.\..+',url,re.DOTALL|re.IGNORECASE).group(1)

// text = some string
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.