Odpowiedź A + jest taka, że jeśli wynikało to z zapomnienia open()pliku z odpowiednim parametrem „newline = ...” dla twojej platformy (uniwersalna obsługa nowego wiersza), być może nie będziesz musiał jawnie go usuwać.
Nie jestem osobą w Pythonie, więc nie mam na to odpowiedzi, ale chomp () Perla faktycznie usuwa separator rekordów wejściowych od końca. Jest to nowa linia na Unixy, ale może być inna (np. Windows) i może być zmienna. Czy istnieje sposób, aby usunąć tę wartość tylko raz z końca łańcucha?
brian d foy
5
brian d foy: Python nie ma separatora rekordów wejściowych, takiego jak awk i Perl.
Peter Hosey,
7
@csde_rats, to nieprawda: OS X używa \nnowych linii tak jak Unix. (Przed OS X MacOS używał \rseparatora linii, ale skończyło się to 10 lat temu.)
skue
21
@briandfoy Python ma wbudowaną obsługę Universal newlines (tylko podczas czytania, a nie podczas pisania). Plik otwierasz w trybie „U” lub „rU”, a następnie niezależnie od systemu Windows, Linux, Mac, cokolwiek, zanim tekst dotrze do kodu Pythona, każdy styl nowej linii został zastąpiony przez „\ n”. Patrz: python.org/dev/peps/pep-0278
AlcubierreDrive,
12
Idę do przodu i przeliteruję to, ponieważ jestem noobem i spędziłem trochę czasu zastanawiając się, dlaczego to nie działa. .strip()nie zmienia łańcucha (prawdopodobnie ma coś wspólnego z niezmiennymi łańcuchami). Jeśli nie w wierszu poleceń, będziesz chciał"string = string.strip()"
Script Kitty
158
Powiedziałbym, że „pytonicznym” sposobem uzyskiwania linii bez znaków końca linii jest splitline ().
Kanonicznym sposobem usuwania znaków końca wiersza (EOL) jest użycie metody string rstrip () usuwającej końcowe \ r lub \ n. Oto przykłady znaków EOL dla komputerów Mac, Windows i Unix.
Użycie „\ r \ n” jako parametru rstrip oznacza, że usunie on dowolną kombinację końcową „\ r” lub „\ n”. Dlatego działa we wszystkich trzech powyższych przypadkach.
Ten niuans ma znaczenie w rzadkich przypadkach. Na przykład kiedyś musiałem przetworzyć plik tekstowy zawierający komunikat HL7. Standard HL7 wymaga znaku „\ r” jako znaku EOL. Komputer z systemem Windows, na którym korzystałem z tego komunikatu, dodał własny znak EOL „\ r \ n”. Dlatego koniec każdej linii wyglądał jak „\ r \ r \ n”. Użycie rstrip („\ r \ n”) usunęłoby całe „\ r \ r \ n”, co nie jest tym, czego chciałem. W takim przypadku po prostu odciąłem dwa ostatnie znaki.
Zauważ, że w przeciwieństwie do chompfunkcji Perla , spowoduje to usunięcie wszystkich określonych znaków na końcu łańcucha, a nie tylko jednego:
Pamiętaj, że nowoczesne aplikacje Mac OS X używają \ n. Używają tylko starych aplikacji Carbon oryginalnie napisanych dla systemu Mac OS.
Peter Hosey,
2
Dziękuję za wyjaśnienie. Oczywiście pas startowy ('\ r \ n') nadal działa w tym przypadku.
Mike,
13
Istnieje również os.linesep, który zawiera sekwencję EOL dla bieżącego systemu operacyjnego.
Eli Collins,
To najlepsza odpowiedź: usuwa tylko nowe linie i robi to poprawnie dla najpopularniejszych platform.
kevinarpe
plus +1 Za użycie \ni\r
fechnert
99
Zauważ, że rstrip nie działa dokładnie tak samo jak chomp () Perla, ponieważ nie modyfikuje łańcucha. To znaczy w Perlu:
$x="a\n";
chomp $x
skutkuje $xbyciem "a".
ale w Pythonie:
x="a\n"
x.rstrip()
oznacza, że wartość xjest nadal"a\n" . Nawet x=x.rstrip()nie zawsze daje taki sam wynik, ponieważ usuwa wszystkie białe znaki z końca łańcucha, a nie tylko jedną nową linię.
Ponadto strip () usuwa powtarzające się znaki, podczas gdy chop / chomp usuwa tylko jedną
nową linię
50
Mogę użyć czegoś takiego:
import os
s = s.rstrip(os.linesep)
Myślę, że problem rstrip("\n")polega na tym, że prawdopodobnie będziesz chciał upewnić się, że separator linii jest przenośny. (podobno używa się niektórych przestarzałych systemów "\r\n"). Inna gotcha polega na rstripusunięciu powtarzających się białych znaków. Mam nadzieję os.linesep, że będzie zawierać właściwe postacie. powyższe działa dla mnie.
Nie zadziała to jednak, jeśli próbujesz wyczyścić treści przesłane przez użytkownika w aplikacji internetowej. Treści użytkownika mogą pochodzić z dowolnego źródła i zawierać dowolne znaki nowej linii.
apiguy
2
Dobra uwaga, z tym wyjątkiem, że możesz przetwarzać pliki „obce” (z przestarzałych systemów) w swoim nowoczesnym systemie operacyjnym.
ChuckCottrill
1
Pamiętaj również, że jeśli czytasz plik w trybie tekstowym, nie będzie to również działać w systemie Windows, ponieważ końcowy znak zawsze zostanie przekonwertowany na „\ n”.
Szalony fizyk
@MadPhysicist Masz rację, że konwertuje go, ale nadal działa, ponieważ jest taki sam rstrip('\r\n')i rstrip()usuwa wszystkie znaki, które są w argumencie.
dtauxe
41
Możesz użyć line = line.rstrip('\n'). Spowoduje to usunięcie wszystkich nowych linii z końca łańcucha, a nie tylko jednego.
Działa to świetnie dla mnie, próbując szybko zamienić plik tekstowy z zakończeniami linii w jedną linię tekstu. Jestem nowicjuszem, więc nie jestem pewien, czy jest lepszy sposób, ale zadziałało, dzięki! (Strip zdawał się działać tylko od końca, a nie wewnętrznie)
Steve Koch
2
Dlaczego nie użyć tylko jednej instrukcji zamiany, takiej jak .replace('\n|\r', '')?
Klamka
2
Na wypadek, gdyby ktokolwiek chciał skorzystać z pomysłu z @DoorknobofSnow, wystarczy niewielka zmiana w użyciu modułu wyrażeń regularnych: import rere.sub('\n|\r', '', '\nx\n\r\n')==> 'x'.
Taylor Edmiston
Wykorzystanie tej techniki i wyrażeń regularnych, jak wspomniano w @TaylorEdmiston, powinno być właściwą odpowiedzią.
Bhargav
@Bhargav Dodałem odpowiedź na to pytanie w oparciu o ten komentarz, jak zasugerowałeś, jednocześnie badając kilka innych powiązanych opcji. Wyjaśniłem również, dlaczego myślę, że wyrażenie regularne jest lepszym rozwiązaniem tego problemu niż str.rstrip, ponieważ tego używa większość odpowiedzi.
Uznanie, jesteś jedynym, który wskazał na ten bardzo ważny szczegół. Jednak, jak ktoś wyżej zauważył, użycie os.linesep nie będzie działać, jeśli czytasz pliki z innego systemu. Może to zająć nieco więcej pracy w Pythonie, w rzeczywistości sprawdzanie końca linii.
brianmearns
19
Ostrożnie z "foo".rstrip(os.linesep): Spowoduje to jedynie zgryzienie znaków nowej linii dla platformy, na której wykonywany jest Twój Python. Wyobraź sobie, że pod Linuksem szczypiesz linie pliku Windows, na przykład:
$ python
Python2.7.1(r271:86832,Mar182011,09:09:48)[GCC 4.5.020100604[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'>>>
Użyj "foo".rstrip("\r\n")zamiast tego, jak mówi Mike powyżej.
Inną rzeczą, na którą należy zwrócić uwagę, jest to, że nie usuwa ona co najwyżej jednej nowej linii, ale w przeciwieństwie do wszystkich nowych linii chomp.
chompFunkcja Perla usuwa jedną sekwencję łamania linii z końca łańcucha tylko wtedy, gdy faktycznie tam jest.
Oto jak planuję to zrobić w Pythonie, jeśli processkoncepcyjnie jest to funkcja, której potrzebuję, aby zrobić coś użytecznego dla każdej linii z tego pliku:
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)
Wreszcie odpowiedź, która usuwa ją tylko raz (podobnie jak w rzeczywistości chomp ...) i jest przenośna dla systemu operacyjnego!
Ciro Santilli 冠状 病毒 审查 六四 事件 法轮功
13
Nie programuję w Pythonie, ale na python.org natknąłem się na często zadawane pytania dotyczące S.rstrip („\ r \ n”) dla Pythona w wersji 2.2 lub nowszej.
Spowoduje to również usunięcie białych znaków tabulacji, których pierwotne pytanie nie wymaga. (Ze względu na znak \ t)
NoahR
9
Uważam, że wygodnie jest mieć możliwość pobierania linii ubijanych w iteratorze, równolegle do sposobu, w jaki można uzyskać niepochmurne linie z obiektu pliku. Możesz to zrobić za pomocą następującego kodu:
Uwaga: Z operator.methodcalleri map( itertools.imapna Py2) można popchnąć tę pracę do warstwy C, unikając Python generator kodu poziom (a tym samym działa nieco szybciej, choć trzeba przyznać I / O koszt jest prawdopodobne, aby zamaskować niewielkie zyski) for line in map(operator.methodcaller('rstrip', '\r\n'), infile):. Nadal można go rozróżnić jako def chomped_lines(it): return map(operator.methodcaller('rstrip', '\r\n'), it).
ShadowRanger,
8
rozwiązanie obejścia dla specjalnego przypadku:
jeśli znak nowej linii jest ostatnim znakiem (jak ma to miejsce w przypadku większości plików wejściowych), to dla dowolnego elementu w kolekcji można indeksować w następujący sposób:
Czasami nowa linia nie jest ostatnim znakiem, ale ostatnimi, szczególnie w systemie Windows, jak zauważyli inni.
Cacovsky
8
Jeśli Twoim zadaniem jest wyczyszczenie wszystkich podziałów linii w obiekcie o wielu liniach str (oldstr), możesz podzielić go na listę zgodnie z ogranicznikiem „\ n”, a następnie dołączyć tę listę do nowego str (newstr).
Wygląda na to, że nie jest to idealne analogowe Perl chomp . W szczególności rstrip nie może obsługiwać wieloznakowych ograniczników nowej linii, takich jak \r\n. Jednak splitlines nie jak wskazał tutaj . Po mojej odpowiedzi na inne pytanie, możesz łączyć złączenia i linie podziału, aby usunąć / zastąpić wszystkie znaki nowej linii s:
''.join(s.splitlines())
Poniższe usuwa dokładnie jedną końcową nową linię (jak sądzę chomp). Przekazywanie Truejako keependsargument linii podziału zachowuje ograniczniki. Następnie ponownie uruchamiane są linie podziału, aby usunąć ograniczniki tylko w ostatniej „linii”:
Mam na uwadze moją odpowiedź opartą na wyrażeniach regularnych z tej, którą zamieściłem wcześniej w komentarzach do innej odpowiedzi. Myślę, że używanie rejest wyraźniejszym i bardziej wyraźnym rozwiązaniem tego problemu niż str.rstrip.
>>>import re
Jeśli chcesz usunąć jeden lub więcej końcowych znaków nowego wiersza:
>>> re.sub(r'[\n\r]+$','','\nx\r\n')'\nx'
Jeśli chcesz wszędzie usuwać znaki nowego wiersza (nie tylko końcowe):
>>> re.sub(r'[\n\r]+','','\nx\r\n')'x'
Jeśli chcesz usunąć tylko 1-2 doczepiany znaki nowej linii (czyli \r, \n, \r\n, \n\r, \r\r, \n\n)
(Ma ?:to na celu utworzenie grupy nie przechwytywania).
(Nawiasem mówiąc, to nie jest to '...'.rstrip('\n', '').rstrip('\r', ''), co może nie być jasne dla innych, którzy natkną się na ten wątek. str.rstripUsuwa tyle znaków, ile to możliwe, więc ciąg taki foo\n\n\ndałby fałszywy wynik pozytywny, foopodczas gdy być może chciałbyś zachować inne znaki nowej linii po usunięciu jednego końcowego).
Za pomocą wyrażenia regularnego możesz pominąć grupę, która nie została przechwycona, nawet w celu ostatecznego podejścia r'\r?\n$'. Prawdopodobnie bardziej wydajny, ponieważ silniki regex mają trudniej optymalizować alternatywy. Zauważ też, że jeśli będziesz to robił wiele razy, będzie to znacznie szybsze (szczególnie jeśli masz do czynienia z innymi rezastosowaniami) re.compilew wyrażeniu raz na raz, a następnie użyj submetody skompilowanego obiektu wyrażenia regularnego; funkcje modułu są na poziomie Pythona i najpierw sprawdzają pamięć podręczną dla skompilowanych wyrażeń regularnych (tworzenie / buforowanie, jeśli brakuje), a następnie wywołują metodę dopasowywania; pomijanie tego wyszukiwania pomaga.
ShadowRanger,
1
Dodatkowo uwaga: Ponieważ próbujesz dopasować \nbezpośrednio, możesz chcieć użyć \Znad $(lub po prostu dopasować \r?$, ponieważ $niejawnie można dopasować tuż przed znakiem nowej linii na końcu łańcucha).
ShadowRanger,
5
>>>' spacious '.rstrip()' spacious'>>>"AABAA".rstrip("A")'AAB'>>>"ABBA".rstrip("AB")# both AB and BA are stripped''>>>"ABCABBA".rstrip("AB")'ABC'
Przykład, którego potrzebowałem! Więc rstrip („\ r \ n”) usunie zarówno „\ n”, jak i „\ r” w dowolnej kombinacji na końcu linii!
Agostino,
@Agostino Nie trzeba podawać "\r\n"Na przykład: ' spacious \n\r\n\r \n\n'.rstrip()produkuje' spacious'
olibre
2
@olibre kod, który sugerujesz, usunie również inne znaki spacji / spacji, które mogą nie być tym, czego potrzeba. W rzeczywistości musiałem tylko usunąć kombinacje znaków eol. Mimo to dziękuję za zwrócenie na to uwagi.
Agostino,
4
Po prostu użyj :
line = line.rstrip("\n")
lub
line = line.strip("\n")
Nie potrzebujesz żadnych z tych skomplikowanych rzeczy
s ='''Hello World \t\n\r\tHi There'''# import the module string import string
# use the method translate to convert
s.translate({ord(c):Nonefor c in string.whitespace}>>'HelloWorldHiThere'
Z wyrażeniem regularnym
s =''' Hello World
\t\n\r\tHi '''print(re.sub(r"\s+","", s), sep='')# \s matches all white spaces>HelloWorldHi
Zamień \ n, \ t, \ r
s.replace('\n','').replace('\t','').replace('\r','')>' Hello World Hi '
Z wyrażeniem regularnym
s ='''Hello World \t\n\r\tHi There'''
regex = re.compile(r'[\n\r\t]')
regex.sub("", s)>'Hello World Hi There'
z Join
s ='''Hello World \t\n\r\tHi There'''' '.join(s.split())>'Hello World Hi There'
Istnieją trzy typy zakończeń linii, które normalnie napotkać: \n, \ri \r\n. Raczej proste wyrażenie regularne w re.submianowicier"\r?\n?$" , jest w stanie złapać je wszystkie.
(I musimy ich wszystkich złapać , mam rację?)
import re
re.sub(r"\r?\n?$","", the_text,1)
Ostatnim argumentem jest ograniczenie liczby zastąpień do jednego, do pewnego stopnia naśladując chomp. Przykład:
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)
Nie potrzebujesz nawet pełnoprawnych wyrażeń regularnych. rstrip("\r\n")jest wszystkim. Spróbować print(text_2.rstrip('\r\n')).
Agostino,
@Agostino: Prawda, biorąc pod uwagę, że to str.rstrip()rozwiązuje problem. To zależy od twoich potrzeb. To rozwiązanie jest wykonany specjalnie dla przypadków, gdy trzeba usunąć tylko ostatnią "\n", "\r"czy "\r\n"jednak nie wszystkie z nich (jeśli istnieje wiele "\n"w ciągu). re.sub(r"\r?\n?$", "", text_1, 1)zwraca "hellothere\n\n"i text_1.rstrip("\r\n")zwraca "hellothere"inny ciąg.
internetowy
To, co próbuję powiedzieć, to: str.strip()to wszystko jest czasem problemem.
internetowy
1
Jeśli martwisz się szybkością (powiedz, że masz długą listę łańcuchów) i znasz charakter znaku nowej linii, przecinanie łańcucha jest w rzeczywistości szybsze niż rstrip. Mały test ilustrujący to:
import time
loops =50000000def 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()
Wiem, że prawdopodobnie powinienem używać „globalnych pętli” wewnątrz funkcji, ale to również działa.
Stephen Miller
Ten test jest nie tak i nie fair .. W method1dopiero odcięcie ostatniego znaku, bez względu na to, w method2tych .rstrip()pierwszych kontroli, jeżeli końca łańcucha znaków zawierającego niepożądane i kotlety je tylko wtedy, gdy niektóre zostały znalezione. Zaimplementuj sprawdzanie znaków method1i ponownie przetestuj!
spky
Jak powiedziałem we wstępie do odpowiedzi: jeśli znasz charakter znaku nowej linii, jest to przydatne. Jeśli nie, to oczywiście musisz wdrożyć sprawdzanie postaci - lub po prostu użyć rstrip. Nie chciałem być „niesprawiedliwy”, aby położyć kres, ale po prostu zilustrować nie tak nieznaczną różnicę, którą warto rozważyć w niektórych sytuacjach.
Stephen Miller
1
Będzie to działać zarówno w systemie Windows, jak i Linux (nieco drogie z re-sub, jeśli szukasz tylko ponownego rozwiązania)
import re
if re.search("(\\r|)\\n$", line):
line = re.sub("(\\r|)\\n$","", line)
open()
pliku z odpowiednim parametrem „newline = ...” dla twojej platformy (uniwersalna obsługa nowego wiersza), być może nie będziesz musiał jawnie go usuwać.Odpowiedzi:
Wypróbuj metodę
rstrip()
(zobacz dokument Python 2 i Python 3 )rstrip()
Metoda Pythona domyślnie usuwa wszystkie końcowe białe znaki, a nie tylko jedną nową linię, jak robi to Perlchomp
.Aby usunąć tylko nowe linie:
Istnieją również metody
lstrip()
istrip()
:źródło
\n
nowych linii tak jak Unix. (Przed OS X MacOS używał\r
separatora linii, ale skończyło się to 10 lat temu.).strip()
nie zmienia łańcucha (prawdopodobnie ma coś wspólnego z niezmiennymi łańcuchami). Jeśli nie w wierszu poleceń, będziesz chciał"string = string.strip()"
Powiedziałbym, że „pytonicznym” sposobem uzyskiwania linii bez znaków końca linii jest splitline ().
źródło
str.splitlines()
traktuje jako nowych linii wielu znaków (nie tylko\r
,\n
)Kanonicznym sposobem usuwania znaków końca wiersza (EOL) jest użycie metody string rstrip () usuwającej końcowe \ r lub \ n. Oto przykłady znaków EOL dla komputerów Mac, Windows i Unix.
Użycie „\ r \ n” jako parametru rstrip oznacza, że usunie on dowolną kombinację końcową „\ r” lub „\ n”. Dlatego działa we wszystkich trzech powyższych przypadkach.
Ten niuans ma znaczenie w rzadkich przypadkach. Na przykład kiedyś musiałem przetworzyć plik tekstowy zawierający komunikat HL7. Standard HL7 wymaga znaku „\ r” jako znaku EOL. Komputer z systemem Windows, na którym korzystałem z tego komunikatu, dodał własny znak EOL „\ r \ n”. Dlatego koniec każdej linii wyglądał jak „\ r \ r \ n”. Użycie rstrip („\ r \ n”) usunęłoby całe „\ r \ r \ n”, co nie jest tym, czego chciałem. W takim przypadku po prostu odciąłem dwa ostatnie znaki.
Zauważ, że w przeciwieństwie do
chomp
funkcji Perla , spowoduje to usunięcie wszystkich określonych znaków na końcu łańcucha, a nie tylko jednego:źródło
os.linesep
, który zawiera sekwencję EOL dla bieżącego systemu operacyjnego.\n
i\r
Zauważ, że rstrip nie działa dokładnie tak samo jak chomp () Perla, ponieważ nie modyfikuje łańcucha. To znaczy w Perlu:
skutkuje
$x
byciem"a"
.ale w Pythonie:
oznacza, że wartość
x
jest nadal"a\n"
. Nawetx=x.rstrip()
nie zawsze daje taki sam wynik, ponieważ usuwa wszystkie białe znaki z końca łańcucha, a nie tylko jedną nową linię.źródło
Mogę użyć czegoś takiego:
Myślę, że problem
rstrip("\n")
polega na tym, że prawdopodobnie będziesz chciał upewnić się, że separator linii jest przenośny. (podobno używa się niektórych przestarzałych systemów"\r\n"
). Inna gotcha polega narstrip
usunięciu powtarzających się białych znaków. Mam nadziejęos.linesep
, że będzie zawierać właściwe postacie. powyższe działa dla mnie.źródło
rstrip('\r\n')
irstrip()
usuwa wszystkie znaki, które są w argumencie.Możesz użyć
line = line.rstrip('\n')
. Spowoduje to usunięcie wszystkich nowych linii z końca łańcucha, a nie tylko jednego.źródło
usunie wszystkie znaki nowej linii na końcu ciągu
s
. Przypisanie jest potrzebne, ponieważrstrip
zwraca nowy ciąg zamiast modyfikować oryginalny ciąg.źródło
Powtórzyłoby to dokładnie chomp perla (minus zachowanie na tablicach) dla terminatora linii „\ n”:
(Uwaga: nie modyfikuje ciągu „na miejscu”; nie usuwa dodatkowych spacji końcowych; bierze pod uwagę \ r \ n)
źródło
lub zawsze możesz dostać geekier z regexps :)
baw się dobrze!
źródło
.replace('\n|\r', '')
?import re
re.sub('\n|\r', '', '\nx\n\r\n')
==>'x'
.możesz użyć paska:
próbny:
źródło
rstrip nie robi tego samego co chomp, na tak wielu poziomach. Przeczytaj http://perldoc.perl.org/functions/chomp.html i przekonaj się, że chomp jest naprawdę bardzo złożony.
Jednak moim głównym celem jest to, że chomp usuwa co najwyżej 1 koniec linii, podczas gdy rstrip usuwa tyle, ile może.
Tutaj możesz zobaczyć rstrip usuwający wszystkie nowe linie:
Znacznie bliższe przybliżenie typowego użycia chrupania Perla można uzyskać za pomocą re.sub, jak poniżej:
źródło
Ostrożnie z
"foo".rstrip(os.linesep)
: Spowoduje to jedynie zgryzienie znaków nowej linii dla platformy, na której wykonywany jest Twój Python. Wyobraź sobie, że pod Linuksem szczypiesz linie pliku Windows, na przykład:Użyj
"foo".rstrip("\r\n")
zamiast tego, jak mówi Mike powyżej.źródło
chomp
.Przykład w dokumentacji Pythona po prostu używa
line.strip()
.chomp
Funkcja Perla usuwa jedną sekwencję łamania linii z końca łańcucha tylko wtedy, gdy faktycznie tam jest.Oto jak planuję to zrobić w Pythonie, jeśli
process
koncepcyjnie jest to funkcja, której potrzebuję, aby zrobić coś użytecznego dla każdej linii z tego pliku:źródło
Nie programuję w Pythonie, ale na python.org natknąłem się na często zadawane pytania dotyczące S.rstrip („\ r \ n”) dla Pythona w wersji 2.2 lub nowszej.
źródło
źródło
Uważam, że wygodnie jest mieć możliwość pobierania linii ubijanych w iteratorze, równolegle do sposobu, w jaki można uzyskać niepochmurne linie z obiektu pliku. Możesz to zrobić za pomocą następującego kodu:
Przykładowe użycie:
źródło
operator.methodcaller
imap
(itertools.imap
na Py2) można popchnąć tę pracę do warstwy C, unikając Python generator kodu poziom (a tym samym działa nieco szybciej, choć trzeba przyznać I / O koszt jest prawdopodobne, aby zamaskować niewielkie zyski)for line in map(operator.methodcaller('rstrip', '\r\n'), infile):
. Nadal można go rozróżnić jakodef chomped_lines(it): return map(operator.methodcaller('rstrip', '\r\n'), it)
.rozwiązanie obejścia dla specjalnego przypadku:
jeśli znak nowej linii jest ostatnim znakiem (jak ma to miejsce w przypadku większości plików wejściowych), to dla dowolnego elementu w kolekcji można indeksować w następujący sposób:
aby wyciąć swój znak nowej linii.
źródło
Jeśli Twoim zadaniem jest wyczyszczenie wszystkich podziałów linii w obiekcie o wielu liniach str (oldstr), możesz podzielić go na listę zgodnie z ogranicznikiem „\ n”, a następnie dołączyć tę listę do nowego str (newstr).
newstr = "".join(oldstr.split('\n'))
źródło
Wygląda na to, że nie jest to idealne analogowe Perl chomp . W szczególności rstrip nie może obsługiwać wieloznakowych ograniczników nowej linii, takich jak
\r\n
. Jednak splitlines nie jak wskazał tutaj . Po mojej odpowiedzi na inne pytanie, możesz łączyć złączenia i linie podziału, aby usunąć / zastąpić wszystkie znaki nowej liniis
:Poniższe usuwa dokładnie jedną końcową nową linię (jak sądzę chomp). Przekazywanie
True
jakokeepends
argument linii podziału zachowuje ograniczniki. Następnie ponownie uruchamiane są linie podziału, aby usunąć ograniczniki tylko w ostatniej „linii”:źródło
Mam na uwadze moją odpowiedź opartą na wyrażeniach regularnych z tej, którą zamieściłem wcześniej w komentarzach do innej odpowiedzi. Myślę, że używanie
re
jest wyraźniejszym i bardziej wyraźnym rozwiązaniem tego problemu niżstr.rstrip
.Jeśli chcesz usunąć jeden lub więcej końcowych znaków nowego wiersza:
Jeśli chcesz wszędzie usuwać znaki nowego wiersza (nie tylko końcowe):
Jeśli chcesz usunąć tylko 1-2 doczepiany znaki nowej linii (czyli
\r
,\n
,\r\n
,\n\r
,\r\r
,\n\n
)Mam uczucie, co większość ludzi naprawdę chcesz tu jest usunięcie tylko jedno wystąpienie znaku nowej linii spływu, albo
\r\n
albo\n
i nic więcej.(Ma
?:
to na celu utworzenie grupy nie przechwytywania).(Nawiasem mówiąc, to nie jest to
'...'.rstrip('\n', '').rstrip('\r', '')
, co może nie być jasne dla innych, którzy natkną się na ten wątek.str.rstrip
Usuwa tyle znaków, ile to możliwe, więc ciąg takifoo\n\n\n
dałby fałszywy wynik pozytywny,foo
podczas gdy być może chciałbyś zachować inne znaki nowej linii po usunięciu jednego końcowego).źródło
r'\r?\n$'
. Prawdopodobnie bardziej wydajny, ponieważ silniki regex mają trudniej optymalizować alternatywy. Zauważ też, że jeśli będziesz to robił wiele razy, będzie to znacznie szybsze (szczególnie jeśli masz do czynienia z innymire
zastosowaniami)re.compile
w wyrażeniu raz na raz, a następnie użyjsub
metody skompilowanego obiektu wyrażenia regularnego; funkcje modułu są na poziomie Pythona i najpierw sprawdzają pamięć podręczną dla skompilowanych wyrażeń regularnych (tworzenie / buforowanie, jeśli brakuje), a następnie wywołują metodę dopasowywania; pomijanie tego wyszukiwania pomaga.\n
bezpośrednio, możesz chcieć użyć\Z
nad$
(lub po prostu dopasować\r?$
, ponieważ$
niejawnie można dopasować tuż przed znakiem nowej linii na końcu łańcucha).źródło
"\r\n"
Na przykład:' spacious \n\r\n\r \n\n'.rstrip()
produkuje' spacious'
Po prostu użyj :
lub
Nie potrzebujesz żadnych z tych skomplikowanych rzeczy
źródło
Z wyrażeniem regularnym
Zamień \ n, \ t, \ r
Z wyrażeniem regularnym
z Join
źródło
Istnieją trzy typy zakończeń linii, które normalnie napotkać:
\n
,\r
i\r\n
. Raczej proste wyrażenie regularne wre.sub
mianowicier"\r?\n?$"
, jest w stanie złapać je wszystkie.(I musimy ich wszystkich złapać , mam rację?)
Ostatnim argumentem jest ograniczenie liczby zastąpień do jednego, do pewnego stopnia naśladując chomp. Przykład:
... gdzie
a == b == c
jestTrue
.źródło
rstrip("\r\n")
jest wszystkim. Spróbowaćprint(text_2.rstrip('\r\n'))
.str.rstrip()
rozwiązuje problem. To zależy od twoich potrzeb. To rozwiązanie jest wykonany specjalnie dla przypadków, gdy trzeba usunąć tylko ostatnią"\n"
,"\r"
czy"\r\n"
jednak nie wszystkie z nich (jeśli istnieje wiele"\n"
w ciągu).re.sub(r"\r?\n?$", "", text_1, 1)
zwraca"hellothere\n\n"
itext_1.rstrip("\r\n")
zwraca"hellothere"
inny ciąg.str.strip()
to wszystko jest czasem problemem.Jeśli martwisz się szybkością (powiedz, że masz długą listę łańcuchów) i znasz charakter znaku nowej linii, przecinanie łańcucha jest w rzeczywistości szybsze niż rstrip. Mały test ilustrujący to:
Wynik:
źródło
method1
dopiero odcięcie ostatniego znaku, bez względu na to, wmethod2
tych.rstrip()
pierwszych kontroli, jeżeli końca łańcucha znaków zawierającego niepożądane i kotlety je tylko wtedy, gdy niektóre zostały znalezione. Zaimplementuj sprawdzanie znakówmethod1
i ponownie przetestuj!Będzie to działać zarówno w systemie Windows, jak i Linux (nieco drogie z re-sub, jeśli szukasz tylko ponownego rozwiązania)
źródło
re.search
czego potrzebujeszre.sub
?Najpierw podziel linie, a następnie połącz je dowolnymi separatorami:
powinien działać jak urok.
źródło
Złap wszystko:
źródło
rstrip
nie przyjmuje wyrażeń regularnych."hi|||\n\n".rstrip("\r|\n")
powroty"hi"