ฉันจะลบบรรทัดใหม่ต่อท้ายได้อย่างไร


1688

chompฟังก์ชันPython เทียบเท่ากับ Perl คืออะไรซึ่งจะลบอักขระตัวสุดท้ายของสตริงหากเป็นบรรทัดใหม่


2
Superset: สตริงใด ๆ แทนที่จะขึ้นบรรทัดใหม่: stackoverflow.com/questions/1038824/ …
Ciro Santilli 冠状病毒病毒审查六四事件法轮功

3
คำตอบ A + คือถ้านี่เป็นเพราะลืมไปยังopen()ไฟล์ที่มีพารามิเตอร์'newline = ... ' ที่เหมาะสมสำหรับแพลตฟอร์มของคุณ (สนับสนุนการขึ้นบรรทัดใหม่สากล) คุณอาจไม่จำเป็นต้องลบมันออกอย่างชัดเจน
smci

คำตอบ:


1868

ลองวิธีการrstrip()(ดู doc Python 2และPython 3 )

>>> 'test string\n'.rstrip()
'test string'

rstrip()วิธีแถบทุกชนิดของช่องว่างต่อท้ายโดยค่าเริ่มต้นไม่ได้เป็นเพียงหนึ่งบรรทัดใหม่เป็น Perl chompจะมี

>>> 'test string \n \r\n\n\r \n\n'.rstrip()
'test string'

หากต้องการตัดเฉพาะบรรทัดใหม่:

>>> 'test string \n \r\n\n\r \n\n'.rstrip('\n')
'test string \n \r\n\n\r '

นอกจากนี้ยังมีวิธีการlstrip()และstrip():

>>> s = "   \n\r\n  \n  abc   def \n\r\n  \n  "
>>> s.strip()
'abc   def'
>>> s.lstrip()
'abc   def \n\r\n  \n  '
>>> s.rstrip()
'   \n\r\n  \n  abc   def'

22
ฉันไม่ใช่คน Python ดังนั้นฉันไม่มีคำตอบนี้ แต่ chomp ของ Perl () จริง ๆ แล้วลบตัวคั่นเร็กคอร์ดอินพุตจากท้ายสุด นั่นคือบรรทัดใหม่ของสิ่ง Unixy แต่อาจแตกต่างกันไป (เช่น Windows) และมันไม่แน่นอน มีวิธีลบค่านั้นเพียงครั้งเดียวจากจุดสิ้นสุดของสตริงหรือไม่
brian d foy

5
brian d foy: Python ไม่มีตัวคั่นเรคคอร์ดอินพุตเช่น awk และ Perl มี
Peter Hosey

7
@csde_rats นั่นไม่ใช่ความจริง: OS X ใช้\nสำหรับการขึ้นบรรทัดใหม่เหมือนกับ Unix (ก่อนที่จะมี OS X, MacOS ได้ใช้\rเป็นตัวคั่นบรรทัด แต่ที่สิ้นสุดวันที่ 10 ปีที่ผ่านมา.)
skue

21
@briandfoy Python ในตัวรองรับ Universal newlines (เฉพาะเมื่ออ่านไม่ใช่ตอนที่เขียน) คุณเปิดไฟล์ในโหมด "U" หรือ "rU" และไม่ว่า Windows, Linux, Mac จะเป็นอะไรก็ตามเมื่อข้อความถึงรหัสไพ ธ อนของคุณบรรทัดใหม่ของรูปแบบใหม่จะถูกแทนที่ด้วย "\ n" ดู: python.org/dev/peps/pep-0278
AlcubierreDrive

12
ฉันจะไปข้างหน้าและสะกดออกเพราะฉัน noob และฉันใช้เวลาสักครู่สงสัยว่าทำไมมันไม่ทำงาน .strip()ไม่เปลี่ยนสตริง (อาจมีบางสิ่งที่เกี่ยวข้องกับสตริงที่ไม่เปลี่ยนรูป) ถ้าไม่อยู่ในบรรทัดคำสั่งคุณจะต้อง"string = string.strip()"
Script Kitty

158

และฉันจะบอกว่าวิธีการ "pythonic" เพื่อรับสายโดยไม่ต้องต่อท้ายอักขระบรรทัดใหม่คือ splitline ()

>>> text = "line 1\nline 2\r\nline 3\nline 4"
>>> text.splitlines()
['line 1', 'line 2', 'line 3', 'line 4']


146

วิธีที่เป็นที่ยอมรับในการตัดอักขระ end-of-line (EOL) คือการใช้เมธอดสตริง rstrip () เพื่อลบส่วนท้าย \ r หรือ \ n นี่คือตัวอย่างสำหรับอักขระ Mac, Windows และ Unix EOL

>>> 'Mac EOL\r'.rstrip('\r\n')
'Mac EOL'
>>> 'Windows EOL\r\n'.rstrip('\r\n')
'Windows EOL'
>>> 'Unix EOL\n'.rstrip('\r\n')
'Unix EOL'

การใช้ '\ r \ n' เป็นพารามิเตอร์ในการ rstrip หมายความว่ามันจะตัดการผสมต่อท้ายใด ๆ ของ '\ r' หรือ '\ n' นั่นเป็นเหตุผลที่ทำงานได้ในทั้งสามกรณีข้างต้น

ความแตกต่างนี้มีความสำคัญในกรณีที่หายาก ตัวอย่างเช่นฉันเคยต้องประมวลผลไฟล์ข้อความที่มีข้อความ HL7 มาตรฐาน HL7 ต้องใช้ '\ r' ต่อท้ายเป็นอักขระ EOL เครื่อง Windows ที่ฉันใช้ข้อความนี้ได้ผนวกอักขระ EOL '\ r \ n' ของตัวเอง ดังนั้นจุดสิ้นสุดของแต่ละบรรทัดจึงดูเหมือน '\ r \ r \ n' การใช้ rstrip ('\ r \ n') น่าจะเอาทั้งหมด '\ r \ r \ n' ซึ่งไม่ใช่สิ่งที่ฉันต้องการ ในกรณีนั้นฉันเพียงแค่ตัดสองอักขระสุดท้ายแทน

โปรดทราบว่าไม่เหมือนกับchompฟังก์ชันของ Perl สิ่งนี้จะตัดอักขระที่ระบุทั้งหมดที่ส่วนท้ายของสตริงไม่ใช่เพียงตัวอักษรเดียว

>>> "Hello\n\n\n".rstrip("\n")
"Hello"

7
โปรดทราบว่าแอป Mac OS X ที่ทันสมัยใช้ \ n เฉพาะแอปพลิเคชันคาร์บอนเก่าที่ถูกเขียนขึ้นสำหรับ Mac OS เท่านั้นที่ใช้ \ r
Peter Hosey

2
ขอขอบคุณสำหรับการชี้แจง. แน่นอนว่า rstrip ('\ r \ n') ยังใช้งานได้ในกรณีนี้เช่นกัน
Mike

13
นอกจากนี้ยังos.linesepมีซึ่งมีลำดับ EOL สำหรับระบบปฏิบัติการปัจจุบัน
Eli Collins

นี่คือคำตอบที่ดีที่สุด: จะตัดเฉพาะการขึ้นบรรทัดใหม่และทำอย่างถูกต้องสำหรับแพลตฟอร์มที่พบบ่อยที่สุด
kevinarpe

บวก +1 สำหรับการใช้\nและ\r
fechnert

99

โปรดทราบว่า rstrip ไม่เหมือนกับ chomp ของ Perl () เพราะมันไม่ได้ปรับเปลี่ยนสตริง นั่นคือใน Perl:

$x="a\n";

chomp $x

ส่งผลให้ความเป็นอยู่$x"a"

แต่ใน Python:

x="a\n"

x.rstrip()

จะหมายความว่าค่าของxเป็นยัง "a\n"แม้x=x.rstrip()จะไม่ได้ผลเหมือนกันเสมอไปเพราะมันตัดช่องว่างทั้งหมดออกจากส่วนท้ายของสตริงไม่ใช่แค่ขึ้นบรรทัดใหม่มากที่สุด


7
นอกจากนี้ strip () ลบอักขระที่ซ้ำกันในขณะที่ chop / chomp ลบหนึ่งบรรทัดใหม่เท่านั้น
kostmo

50

ฉันอาจใช้สิ่งนี้:

import os
s = s.rstrip(os.linesep)

ฉันคิดว่าปัญหาที่เกิดขึ้นrstrip("\n")คือคุณอาจต้องการตรวจสอบให้แน่ใจว่าตัวแยกบรรทัดเป็นแบบพกพา (ระบบโบราณบางระบบมีข่าวลือให้ใช้"\r\n") gotcha อื่น ๆ ที่rstripจะตัดช่องว่างซ้ำออกมา หวังว่าos.linesepจะมีตัวอักษรที่เหมาะสม ข้างต้นใช้งานได้สำหรับฉัน


12
สิ่งนี้จะไม่ทำงานหากคุณพยายามล้างเนื้อหาที่ผู้ใช้ส่งในเว็บแอปพลิเคชัน เนื้อหาของผู้ใช้อาจมาจากแหล่งใด ๆ และมีตัวอักษรขึ้นบรรทัดใหม่
apiguy

2
จุดที่ดียกเว้นว่าคุณอาจประมวลผลไฟล์ 'ต่างประเทศ' (จากระบบโบราณ) บนระบบปฏิบัติการสมัยใหม่ของคุณ
ChuckCottrill

1
โปรดทราบว่าหากคุณกำลังอ่านไฟล์ในโหมดข้อความสิ่งนี้จะไม่ทำงานบนระบบ Windows เช่นกันเนื่องจากอักขระตัวต่อท้ายจะถูกแปลงเป็น '\ n' เสมอ
นักฟิสิกส์บ้า

@MadPhysicist คุณถูกต้องที่จะแปลงมัน แต่ก็ยังใช้งานได้เพราะมันเหมือนกันrstrip('\r\n')และrstrip()จะดึงตัวละครที่อยู่ในการโต้แย้ง
dtauxe

41

line = line.rstrip('\n')คุณอาจจะใช้ สิ่งนี้จะตัดการขึ้นบรรทัดใหม่ทั้งหมดจากจุดสิ้นสุดของสตริงไม่ใช่แค่หนึ่งบรรทัด


35
s = s.rstrip()

sจะลบบรรทัดใหม่ทั้งหมดในตอนท้ายของสตริง การกำหนดเป็นสิ่งจำเป็นเนื่องจากrstripส่งคืนสตริงใหม่แทนการแก้ไขสตริงเดิม


33

สิ่งนี้จะทำซ้ำ chomp ของ perl (ลบพฤติกรรมในอาร์เรย์) ของตัวคั่นบรรทัด "\ n":

def chomp(x):
    if x.endswith("\r\n"): return x[:-2]
    if x.endswith("\n") or x.endswith("\r"): return x[:-1]
    return x

(หมายเหตุ: มันไม่ได้แก้ไขสตริง 'ในสถานที่' มันไม่ได้ตัดช่องว่างต่อท้ายพิเศษใช้เวลา \ r \ n ในบัญชี)


27
"line 1\nline 2\r\n...".replace('\n', '').replace('\r', '')
>>> 'line 1line 2...'

หรือคุณสามารถรับ geekier ด้วย regexps :)

มีความสุข!


สิ่งนี้ใช้ได้ผลดีมากสำหรับฉันที่พยายามเปลี่ยนไฟล์ข้อความด้วยการลงท้ายบรรทัดให้เป็นข้อความบรรทัดเดียว ฉันเป็นมือใหม่ดังนั้นไม่แน่ใจว่ามีวิธีที่ดีกว่าที่จะทำ แต่มันได้ผลขอบคุณ! (รางดูเหมือนจะทำงานเฉพาะจากปลายไม่ใช่ภายใน)
สตีฟ Koch

2
ทำไมไม่ใช้เพียงหนึ่งคำสั่งแทนที่เช่น.replace('\n|\r', '')?
Doorknob

2
เพียงในกรณีที่คนอื่นต้องการที่จะใช้ความคิดจาก @DoorknobofSnow มันเป็นเพียงการเปลี่ยนแปลงเล็ก ๆ ที่จะใช้โมดูล regex นี้: ==>import re re.sub('\n|\r', '', '\nx\n\r\n') 'x'
เทย์เลอร์เอ็ดมิสตัน

การใช้เทคนิคนี้และ regex ดังที่ @TaylorEdmiston ที่กล่าวถึงควรเป็นคำตอบที่เหมาะสม
Bhargav

@Bhargav ฉันได้เพิ่มคำตอบสำหรับคำถามนี้ตามความคิดเห็นที่คุณแนะนำขณะที่สำรวจตัวเลือกอื่น ๆ ที่เกี่ยวข้อง ฉันยังชี้แจงด้วยว่าเหตุใดฉันคิดว่า regex เป็นวิธีแก้ปัญหาที่ดีกว่า str.rstrip เนื่องจากเป็นคำตอบที่ใช้มากที่สุด
Taylor Edmiston

27

คุณสามารถใช้แถบ:

line = line.strip()

การสาธิต:

>>> "\n\n hello world \n\n".strip()
'hello world'

1
พยายามแก้ปัญหานี้ แต่มันดึงแถบว่างชั้นนำในบรรทัด
Tarik

@Tarik คุณสามารถใช้ rstrip
Hackaholic

rstrip จะลบช่องว่างต่อท้ายทั้งหมดซึ่งแตกต่างจาก chomp ซึ่งจะลบบรรทัดใหม่มากที่สุดเพียงบรรทัดเดียว
Flimm

20

rstrip ไม่ได้ทำสิ่งเดียวกันกับ chomp ในหลาย ๆ ระดับ อ่านhttp://perldoc.perl.org/functions/chomp.htmlและดูว่า chomp ซับซ้อนมากแน่นอน

อย่างไรก็ตามประเด็นหลักของฉันคือ chomp ลบที่ส่วนท้ายสุด 1 บรรทัดในขณะที่ rstrip จะลบมากที่สุดเท่าที่จะทำได้

ที่นี่คุณสามารถเห็น rstrip ลบบรรทัดใหม่ทั้งหมด:

>>> 'foo\n\n'.rstrip(os.linesep)
'foo'

การประมาณการใช้ Perl chomp โดยทั่วไปที่ใกล้เคียงมากขึ้นสามารถทำได้ด้วย re.sub เช่นนี้

>>> re.sub(os.linesep + r'\Z','','foo\n\n')
'foo\n'

2
รุ่งโรจน์คุณเป็นคนเดียวที่ชี้ให้เห็นรายละเอียดที่สำคัญมากนี้ อย่างไรก็ตามตามที่มีคนกล่าวไว้ข้างต้นการใช้ os.linesep จะไม่ทำงานหากคุณอ่านไฟล์จากระบบอื่น นี่อาจใช้เวลาทำงานอีกเล็กน้อยใน Python ตรวจสอบจุดสิ้นสุดของบรรทัด
brianmearns

19

ระวังด้วย"foo".rstrip(os.linesep): นั่นจะทำให้ตัวละครขึ้นบรรทัดใหม่สำหรับแพลตฟอร์มที่ใช้งาน Python ของคุณเท่านั้น ลองจินตนาการว่าคุณกำลังทำให้ไฟล์ใน Windows ภายใต้ Linux เป็นตัวอย่าง:

$ python
Python 2.7.1 (r271:86832, Mar 18 2011, 09:09:48) 
[GCC 4.5.0 20100604 [gcc-4_5-branch revision 160292]] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import os, sys
>>> sys.platform
'linux2'
>>> "foo\r\n".rstrip(os.linesep)
'foo\r'
>>>

ใช้"foo".rstrip("\r\n")แทนอย่างที่ Mike พูดด้านบน


สิ่งอื่น ๆ ที่จะต้องทราบก็คือว่ามันไม่ได้ลบมากที่สุดคนหนึ่งขึ้นบรรทัดใหม่ chompแต่การขึ้นบรรทัดใหม่ทั้งหมดซึ่งแตกต่างจาก
Flimm

19

เช่นในเอกสารของงูใหญ่line.strip()เพียงแค่ใช้

chompฟังก์ชั่นของ Perl ลบลำดับบรรทัดเดียวออกจากจุดสิ้นสุดของสตริงเฉพาะถ้ามันมีจริง

นี่คือวิธีที่ฉันวางแผนที่จะทำเช่นนั้นใน Python ถ้าprocessเป็นแนวคิดฟังก์ชั่นที่ฉันต้องการเพื่อทำสิ่งที่มีประโยชน์สำหรับแต่ละบรรทัดจากไฟล์นี้:

import os
sep_pos = -len(os.linesep)
with open("file.txt") as f:
    for line in f:
        if line[sep_pos:] == os.linesep:
            line = line[:sep_pos]
        process(line)

2
ในที่สุดคำตอบที่เอาออกเพียงครั้งเดียว (เช่น chomp ที่เกิดขึ้นจริง ... ) และเป็นระบบปฏิบัติการแบบพกพา!
Ciro Santilli 法轮功病毒审查六四事件法轮功


10
import re

r_unwanted = re.compile("[\n\t\r]")
r_unwanted.sub("", your_text)

2
นี่จะเป็นการลบพื้นที่ว่างแท็บด้วยซึ่งคำถามเดิมไม่ได้ร้องขอ (เนื่องจากตัวละคร \ t)
NoahR

9

ฉันคิดว่ามันสะดวกที่จะสามารถรับสาย chomped ผ่านในตัววนซ้ำขนานกับวิธีที่คุณสามารถรับสายที่ไม่ได้ chomped จากวัตถุไฟล์ คุณสามารถทำได้ด้วยรหัสต่อไปนี้:

def chomped_lines(it):
    return map(operator.methodcaller('rstrip', '\r\n'), it)

ตัวอย่างการใช้งาน:

with open("file.txt") as infile:
    for line in chomped_lines(infile):
        process(line)

หมายเหตุ: ด้วยoperator.methodcallerและmap( itertools.imapใน Py2) คุณสามารถผลักดันงานนี้ไปยังชั้น C หลีกเลี่ยงงูหลามรหัสเครื่องกำเนิดไฟฟ้าระดับ (และจึงวิ่งบิตเร็วขึ้น แต่ยอมรับ I / O for line in map(operator.methodcaller('rstrip', '\r\n'), infile):ค่าใช้จ่ายมีแนวโน้มที่จะสวมหน้ากากกำไรเล็ก): def chomped_lines(it): return map(operator.methodcaller('rstrip', '\r\n'), it)มันอาจจะยังคงได้รับปัจจัยจากการเป็น
ShadowRanger

8

วิธีแก้ปัญหาสำหรับกรณีพิเศษ:

หากอักขระขึ้นบรรทัดใหม่เป็นอักขระตัวสุดท้าย (ตามที่เป็นกรณีที่มีอินพุตไฟล์ส่วนใหญ่) ดังนั้นสำหรับองค์ประกอบใด ๆ ในคอลเลกชันคุณสามารถสร้างดัชนีได้ดังนี้:

foobar= foobar[:-1]

เพื่อแบ่งอักขระขึ้นบรรทัดใหม่ของคุณ


3
บางครั้งการขึ้นบรรทัดใหม่ไม่ตัวอักษรตัวสุดท้าย แต่คนสุดท้ายที่พิเศษบน windows เป็นคนอื่นได้ชี้ให้เห็น
Cacovsky

8

หากคำถามของคุณคือการล้างการขึ้นบรรทัดใหม่ทั้งหมดในวัตถุหลายบรรทัด str (oldstr) คุณสามารถแบ่งออกเป็นรายการตามตัวคั่น '\ n' จากนั้นเข้าร่วมรายการนี้เป็น str ใหม่ (newstr)

newstr = "".join(oldstr.split('\n'))


7

ดูเหมือนว่ามีไม่ได้เป็นอะนาล็อกที่สมบูรณ์แบบสำหรับของ Perl chomp โดยเฉพาะอย่างยิ่งrstripไม่สามารถจัดการตัวคั่นบรรทัดใหม่หลายตัวละคร\r\nได้ อย่างไรก็ตามsplitlinesไม่เป็นแหลมออกจากที่นี่ ทำตามคำตอบของฉันในคำถามที่แตกต่างกันคุณสามารถรวมเข้าร่วมและแยกเพื่อลบ / แทนที่บรรทัดใหม่ทั้งหมดจากสตริงs:

''.join(s.splitlines())

ต่อไปนี้จะลบnewline ต่อท้ายหนึ่งบรรทัด (อย่างที่ฉันเชื่อว่า chomp) ผ่านTrueเป็นkeependsอาร์กิวเมนต์เพื่อแยกบรรทัดเก็บตัวคั่น จากนั้นเส้นแบ่งจะถูกเรียกอีกครั้งเพื่อลบตัวคั่นบน "บรรทัด" สุดท้าย:

def chomp(s):
    if len(s):
        lines = s.splitlines(True)
        last = lines.pop()
        return ''.join(lines + last.splitlines())
    else:
        return ''

7

ฉันตอบคำถามตามนิพจน์ปกติของฉันจากโพสต์ก่อนหน้านี้ในข้อคิดเห็นของคำตอบอื่น ฉันคิดว่าการใช้reเป็นวิธีแก้ปัญหาที่ชัดเจนกว่าstr.rstripนี้

>>> import re

หากคุณต้องการที่จะลบหนึ่งหรือมากกว่าต่อท้ายตัวอักษรขึ้นบรรทัดใหม่:

>>> re.sub(r'[\n\r]+$', '', '\nx\r\n')
'\nx'

หากคุณต้องการลบตัวอักษรขึ้นบรรทัดใหม่ทุกที่ (ไม่ใช่แค่ตามท้าย):

>>> re.sub(r'[\n\r]+', '', '\nx\r\n')
'x'

หากคุณต้องการที่จะลบเพียง 1-2 ตัวอักษรขึ้นบรรทัดใหม่ต่อท้าย (เช่น\r, \n, \r\n, \n\r, \r\r, \n\n)

>>> re.sub(r'[\n\r]{1,2}$', '', '\nx\r\n\r\n')
'\nx\r'
>>> re.sub(r'[\n\r]{1,2}$', '', '\nx\r\n\r')
'\nx\r'
>>> re.sub(r'[\n\r]{1,2}$', '', '\nx\r\n')
'\nx'

ฉันรู้สึกว่าสิ่งที่คนส่วนใหญ่ต้องการจริงๆที่นี่คือการลบอักขระบรรทัดใหม่ที่ต่อท้ายเพียงรายการเดียวไม่ว่าจะอย่างใดอย่างหนึ่ง\r\nหรือ\nมากกว่านั้น

>>> re.sub(r'(?:\r\n|\n)$', '', '\nx\n\n', count=1)
'\nx\n'
>>> re.sub(r'(?:\r\n|\n)$', '', '\nx\r\n\r\n', count=1)
'\nx\r\n'
>>> re.sub(r'(?:\r\n|\n)$', '', '\nx\r\n', count=1)
'\nx'
>>> re.sub(r'(?:\r\n|\n)$', '', '\nx\n', count=1)
'\nx'

( ?:คือการสร้างกลุ่มที่ไม่จับภาพ)

(โดยวิธีการนี้ไม่ใช่สิ่ง'...'.rstrip('\n', '').rstrip('\r', '')ที่อาจไม่ชัดเจนสำหรับผู้อื่นที่สะดุดเมื่อเธรดนี้ str.rstripดึงอักขระที่ต่อท้ายมากที่สุดเท่าที่เป็นไปได้ดังนั้นสตริงที่เหมือนfoo\n\n\nจะส่งผลในเชิงบวกผิด ๆ ในfooขณะที่คุณอาจต้องการรักษา ขึ้นบรรทัดใหม่อื่น ๆ หลังจากทำการลากส่วนท้ายหนึ่งอัน)


คุณสามารถข้ามกลุ่มที่ไม่ใช่จับแม้สำหรับวิธีการสุดท้ายของคุณกับ r'\r?\n$'regex มีประสิทธิภาพมากขึ้นเนื่องจากเอ็นจิ้นของ regex มีช่วงเวลาที่ยากขึ้นในการปรับการสับเปลี่ยน นอกจากนี้โปรดทราบว่าหากคุณจะทำเช่นนี้หลาย ๆ ครั้งมันจะเร็วขึ้นอย่างมาก (โดยเฉพาะถ้าคุณผสมกับการreใช้งานอื่น ๆ) ในre.compileการแสดงออกครั้งเดียวล่วงหน้าจากนั้นใช้subวิธีการของวัตถุ regex ที่รวบรวม ฟังก์ชั่นโมดูลเป็นระดับ Python และตรวจสอบแคชสำหรับการรวบรวม regexes ก่อน (การสร้าง / แคชหากไม่มี) จากนั้นเรียกวิธีการจับคู่; การข้ามการค้นหานั้นช่วยได้
ShadowRanger

1
หมายเหตุด้านข้าง: เนื่องจากคุณพยายามจับคู่\nโดยตรงคุณอาจต้องการใช้\Zเกิน$(หรือเพียงแค่จับคู่\r?$เนื่องจาก$โดยปริยายสามารถจับคู่ก่อนขึ้นบรรทัดใหม่ในตอนท้ายของสตริง)
ShadowRanger

5
>>> '   spacious   '.rstrip()
'   spacious'
>>> "AABAA".rstrip("A")
  'AAB'
>>> "ABBA".rstrip("AB") # both AB and BA are stripped
   ''
>>> "ABCABBA".rstrip("AB")
   'ABC'

ตัวอย่างที่ฉันต้องการ! ดังนั้น rstrip ("\ r \ n") จะตัดทั้ง '\ n' และ '\ r' ในชุดใด ๆ ที่ท้ายบรรทัด!
Agostino

@Agostino ไม่จำเป็นต้องให้"\r\n"ตัวอย่างเช่น: ' spacious \n\r\n\r \n\n'.rstrip()ผลิต' spacious'
olibre

2
@olibre รหัสที่คุณแนะนำจะตัดอักขระช่องว่าง / ช่องว่างอื่น ๆ ซึ่งอาจไม่ใช่สิ่งที่ต้องการ ที่จริงแล้วฉันต้องการตัดชุดอักขระ eol เท่านั้น ยังคงขอบคุณที่ชี้ให้เห็น
Agostino


4
s = '''Hello  World \t\n\r\tHi There'''
# import the module string   
import string
# use the method translate to convert 
s.translate({ord(c): None for c in string.whitespace}
>>'HelloWorldHiThere'

ด้วย regex

s = '''  Hello  World 
\t\n\r\tHi '''
print(re.sub(r"\s+", "", s), sep='')  # \s matches all white spaces
>HelloWorldHi

แทนที่ \ n, \ t, \ r

s.replace('\n', '').replace('\t','').replace('\r','')
>'  Hello  World Hi '

ด้วย regex

s = '''Hello  World \t\n\r\tHi There'''
regex = re.compile(r'[\n\r\t]')
regex.sub("", s)
>'Hello  World Hi There'

ด้วยการเข้าร่วม

s = '''Hello  World \t\n\r\tHi There'''
' '.join(s.split())
>'Hello  World Hi There'

3

มีสามประเภทของปลายสายที่เรามักพบคือ\n, และ\r \r\nการแสดงออกปกติค่อนข้างง่ายre.subคือr"\r?\n?$"สามารถจับพวกเขาทั้งหมด

(และเราต้องจับพวกเขาทั้งหมดใช่มั้ย)

import re

re.sub(r"\r?\n?$", "", the_text, 1)

ด้วยการโต้แย้งครั้งสุดท้ายเรา จำกัด จำนวนการเกิดขึ้นที่ถูกแทนที่ด้วยสิ่งเดียวซึ่งเป็นการลอกเลียนแบบในระดับหนึ่ง ตัวอย่าง:

import re

text_1 = "hellothere\n\n\n"
text_2 = "hellothere\n\n\r"
text_3 = "hellothere\n\n\r\n"

a = re.sub(r"\r?\n?$", "", text_1, 1)
b = re.sub(r"\r?\n?$", "", text_2, 1)
c = re.sub(r"\r?\n?$", "", text_3, 1)

... ที่เป็นa == b == cTrue


คุณไม่จำเป็นต้องมีการแสดงออกปกติเต็มรูปแบบ rstrip("\r\n")เป็นสิ่งที่จับได้ทั้งหมด ลองprint(text_2.rstrip('\r\n'))ดู
Agostino

@Agostino: จริงให้การstr.rstrip()แก้ปัญหา ขึ้นอยู่กับความต้องการของคุณ การแก้ปัญหานี้จะทำเฉพาะสำหรับกรณีเมื่อคุณต้องการที่จะลบเพียงสุดท้าย"\n", "\r"หรือ"\r\n"แต่ไม่ทั้งหมดของพวกเขา (ถ้ามีหลาย"\n"ในสตริง) re.sub(r"\r?\n?$", "", text_1, 1)ผลตอบแทน"hellothere\n\n"และtext_1.rstrip("\r\n")ผลตอบแทน"hellothere"ซึ่งเป็นสตริงที่แตกต่างกัน
อินเทอร์เน็ต

สิ่งที่ฉันพยายามจะพูดคือนั่นstr.strip()คือสิ่งที่จับได้บางครั้งก็เป็นปัญหาอย่างมาก
อินเทอร์เน็ต

1

หากคุณกังวลเกี่ยวกับความเร็ว (สมมติว่าคุณมีรายการสตริงที่ยาวเหยียด) และคุณรู้ว่าลักษณะของอักขระขึ้นบรรทัดใหม่การแบ่งสตริงเป็นจริงเร็วกว่า rstrip การทดสอบเล็กน้อยเพื่ออธิบายสิ่งนี้:

import time

loops = 50000000

def method1(loops=loops):
    test_string = 'num\n'
    t0 = time.time()
    for num in xrange(loops):
        out_sting = test_string[:-1]
    t1 = time.time()
    print('Method 1: ' + str(t1 - t0))

def method2(loops=loops):
    test_string = 'num\n'
    t0 = time.time()
    for num in xrange(loops):
        out_sting = test_string.rstrip()
    t1 = time.time()
    print('Method 2: ' + str(t1 - t0))

method1()
method2()

เอาท์พุท:

Method 1: 3.92700004578
Method 2: 6.73000001907

ฉันรู้ว่าฉันควรใช้ "ลูปโกลบอล" ภายในฟังก์ชั่น แต่ก็ใช้งานได้เช่นกัน
Stephen Miller

การทดสอบนี้ผิดและไม่ยุติธรรม .. method1คุณเพียงแค่ตัดอักขระตัวสุดท้ายไม่ว่าจะเกิดอะไรขึ้นในmethod2การ.rstrip()ตรวจสอบครั้งแรกหากการสิ้นสุดของสตริงมีอักขระที่ไม่พึงประสงค์และตัดออกหากพบบางอย่างเท่านั้น โปรดใช้การตรวจสอบตัวละครmethod1และทดสอบความเจ็บปวด!
spky

ดังที่ฉันได้กล่าวไว้ในคำตอบสำหรับคำแนะนำ: หากคุณรู้ว่าลักษณะของอักขระขึ้นบรรทัดใหม่สิ่งนี้มีประโยชน์ หากคุณไม่ได้ใช่คุณจะต้องใช้การตรวจสอบอักขระอย่างชัดเจน - หรือใช้ rstrip ฉันไม่ได้หมายความว่าจะ "ไม่ยุติธรรม" ในการ rstrip แต่เพียงแสดงให้เห็นถึงความแตกต่างที่ไม่มีนัยสำคัญที่อาจคุ้มค่าในการพิจารณาในบางสถานการณ์
Stephen Miller

1

สิ่งนี้จะทำงานได้ทั้งกับ windows และ linux (ราคาแพงไปอีกเล็กน้อยหากคุณกำลังมองหาวิธีแก้ปัญหาเท่านั้น)

import re 
if re.search("(\\r|)\\n$", line):
    line = re.sub("(\\r|)\\n$", "", line)


3
ทำไมต้องใช้re.searchที่คุณเพียงแค่ต้องre.sub?
wjandrea


-1

จับทั้งหมด:

line = line.rstrip('\r|\n')

5
rstripไม่แสดงออกอย่างสม่ำเสมอ "hi|||\n\n".rstrip("\r|\n")ผลตอบแทน"hi"
Flimm
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.