chompBir dizgenin yeni satırsa son karakterini kaldıran Perl işlevinin Python eşdeğeri nedir ?
open()uygun 'newline = ...' parametresine (evrensel newline desteği) sahip bir dosyayı unutması nedeniyle açık bir şekilde kaldırmanız gerekmeyebilir.
chompBir dizgenin yeni satırsa son karakterini kaldıran Perl işlevinin Python eşdeğeri nedir ?
open()uygun 'newline = ...' parametresine (evrensel newline desteği) sahip bir dosyayı unutması nedeniyle açık bir şekilde kaldırmanız gerekmeyebilir.
Yanıtlar:
Yöntemi deneyin rstrip()(bkz. Doc Python 2 ve Python 3 )
>>> 'test string\n'.rstrip()
'test string'
Python'un rstrip()yöntemi , Perl'in yaptığı gibi sadece bir satırsonu değil, varsayılan olarak her türlü sondaki boşlukları ayırır chomp.
>>> 'test string \n \r\n\n\r \n\n'.rstrip()
'test string'
Yalnızca yeni satırları ayırmak için:
>>> 'test string \n \r\n\n\r \n\n'.rstrip('\n')
'test string \n \r\n\n\r '
Ayrıca yöntemler lstrip()ve 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'
\nUnix gibi yeni satırlar için kullanır . (OS X'ten önce MacOS, \rhat ayırıcı olarak kullanıyordu , ancak bu 10 yıl önce sona erdi.)
.strip()dizeyi değiştirmez (muhtemelen değişmez dizelerle ilgisi vardır). Komut satırında değilse, isteyeceksiniz"string = string.strip()"
Ve yeni satır karakterlerini izlemeden satır almanın "pythonic" yolunun splitlines () olduğunu söyleyebilirim.
>>> text = "line 1\nline 2\r\nline 3\nline 4"
>>> text.splitlines()
['line 1', 'line 2', 'line 3', 'line 4']
Satır sonu (EOL) karakterlerini ayırmanın kurallı yolu, izleyen \ r veya \ n dizesini kaldırmak için string rstrip () yöntemini kullanmaktır. Aşağıda Mac, Windows ve Unix EOL karakterlerine örnekler verilmiştir.
>>> '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'
Rstrip parametresi olarak '\ r \ n' kullanılması, herhangi bir '\ r' veya '\ n' kombinasyonunu kaldırması anlamına gelir. Bu yüzden yukarıdaki üç durumda da çalışır.
Bu nüans nadir durumlarda önemlidir. Örneğin, bir zamanlar bir HL7 mesajı içeren bir metin dosyasını işlemek zorunda kaldım. HL7 standardı, EOL karakteri olarak bir "r" gerektirir. Bu iletiyi kullandığım Windows makinesi kendi '\ r \ n' EOL karakterini eklemişti. Bu nedenle, her satırın sonu '\ r \ r \ n' gibi görünüyordu. Rstrip ('\ r \ n') kullanmak istediğim gibi olmayan tüm '\ r \ r \ n' kodunu çıkarırdı. Bu durumda, sadece son iki karakteri dilimledim.
Perl chompişlevinden farklı olarak , bunun yalnızca bir değil, dizenin sonunda belirtilen tüm karakterleri sileceğini unutmayın:
>>> "Hello\n\n\n".rstrip("\n")
"Hello"
os.linesepMevcut işletim sistemi için EOL dizisini içeren de vardır .
\nve\r
Dizgeyi değiştirmediği için rstrip komutunun Perl chomp () işlevi görmediğini unutmayın. Yani, Perl'de:
$x="a\n";
chomp $x
sonuçlanır $xolmak "a".
ama Python'da:
x="a\n"
x.rstrip()
değerinin halax olduğu anlamına gelir . Hatta her zaman aynı sonucu vermez, çünkü en fazla bir satırsonu değil, tüm boşlukları dizenin sonundan ayırır. "a\n"x=x.rstrip()
Ben böyle bir şey kullanabilirsiniz:
import os
s = s.rstrip(os.linesep)
Bence sorun rstrip("\n")muhtemelen çizgi ayırıcı taşınabilir olduğundan emin olmak isteyeceksiniz. (bazı eski sistemlerin kullanıldığı söyleniyor "\r\n"). Diğer sorun ise rstriptekrarlanan boşlukları çıkaracak. Umarım os.linesepdoğru karakterleri içerir. yukarıdakiler benim için çalışıyor.
rstrip('\r\n')ve rstrip()şerit olacak.
Bu, "\ n" satır sonlandırıcısı için perl kodunu (dizilerde eksi davranış) tam olarak çoğaltır:
def chomp(x):
if x.endswith("\r\n"): return x[:-2]
if x.endswith("\n") or x.endswith("\r"): return x[:-1]
return x
(Not: 'yerinde' dizesini değiştirmez; fazladan boşluk bırakmaz; \ r \ n dikkate alır)
"line 1\nline 2\r\n...".replace('\n', '').replace('\r', '')
>>> 'line 1line 2...'
ya da her zaman regexps ile geekier alabilirsiniz :)
iyi eğlenceler!
.replace('\n|\r', '')?
import re re.sub('\n|\r', '', '\nx\n\r\n')==> 'x'.
şerit kullanabilirsiniz:
line = line.strip()
demo:
>>> "\n\n hello world \n\n".strip()
'hello world'
rstrip pek çok seviyede chomp ile aynı şeyi yapmaz. Http://perldoc.perl.org/functions/chomp.html adresini okuyun ve chomp'ın gerçekten çok karmaşık olduğunu görün.
Ancak, asıl amacım chomp en fazla 1 satır sonunu kaldırırken, rstrip olabildiğince fazla kaldıracaktır.
Burada rstrip'in tüm yeni satırları kaldırdığını görebilirsiniz:
>>> 'foo\n\n'.rstrip(os.linesep)
'foo'
Re.sub ile tipik Perl pirzolası kullanımının çok daha yakın bir şekilde gerçekleştirilmesi mümkündür, örneğin:
>>> re.sub(os.linesep + r'\Z','','foo\n\n')
'foo\n'
Dikkatli olun "foo".rstrip(os.linesep): Bu yalnızca Python'unuzun yürütüldüğü platform için yeni satır karakterlerini chomp eder. Linux altında bir Windows dosyasının satırlarını şımarttığınızı düşünün, örneğin:
$ 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")Bunun yerine Mike'ın yukarıda söylediği gibi kullanın .
chomp.
Python'un belgelerindeki bir örnek sadece kullanır line.strip().
Perl chompişlevi, bir satır sonu dizisini yalnızca gerçekten varsa bir dizenin sonundan kaldırır.
Python, bunu processkavramsal olarak bu dosyadan her satır için yararlı bir şey yapmak için gereken işlev ise nasıl planlıyoruz :
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)
Python'da program yapmıyorum, ancak python.org'da S.rstrip'i ("\ r \ n") savunan bir python 2.2 veya üstü için SSS ile karşılaştım.
import re
r_unwanted = re.compile("[\n\t\r]")
r_unwanted.sub("", your_text)
Bir dosya nesnesinden kesilmemiş satırları alabilmenize paralel olarak, kesikli satırları yineleyici aracılığıyla elde edebilmeyi uygun buluyorum. Bunu aşağıdaki kodla yapabilirsiniz:
def chomped_lines(it):
return map(operator.methodcaller('rstrip', '\r\n'), it)
Örnek kullanım:
with open("file.txt") as infile:
for line in chomped_lines(infile):
process(line)
operator.methodcallerve map( itertools.imapPython seviyesi jeneratör kodunu kaçınarak (ve böylece olsa kuşkusuz I / O havai küçük kazançlar maskelemek muhtemeldir, biraz daha hızlı çalıştıran), C katmanına bu işi itebilir Py2 üzerine): for line in map(operator.methodcaller('rstrip', '\r\n'), infile):. Yine de çarpanlarına ayrılabilir def chomped_lines(it): return map(operator.methodcaller('rstrip', '\r\n'), it).
özel durum için geçici çözüm:
eğer yeni satır karakteri son karakter ise (çoğu dosya girişinde olduğu gibi), o zaman koleksiyondaki herhangi bir eleman için aşağıdaki gibi indeksleyebilirsiniz:
foobar= foobar[:-1]
yeni satır karakterinizi dilimlemek için.
Perl'in chomp için mükemmel bir analog yok gibi görünüyor . Özellikle, rstrip gibi çok karakterli yeni satır sınırlayıcılarını işleyemez \r\n. Ancak, splitlines burada belirtildiği gibi yapar . Farklı bir soru hakkındaki cevabımı takiben , bir dizeden tüm yeni satırları kaldırmak / değiştirmek için birleştirme ve ayırma çizgilerini birleştirebilirsinizs :
''.join(s.splitlines())
Aşağıdaki kaldırır tam olarak bir arka satır (chomp, ben inanmak). Geçme Trueolarak keependssplitlines için argüman ayraçları korur. Ardından, yalnızca son "satır" daki sınırlayıcıları kaldırmak için tekrar bölme çizgileri çağrılır:
def chomp(s):
if len(s):
lines = s.splitlines(True)
last = lines.pop()
return ''.join(lines + last.splitlines())
else:
return ''
Daha önce başka bir cevabın yorumlarında gönderdiğim birinden düzenli ifade temelli cevabımı fırlatıyorum. Bence kullanmak rebu soruna göre daha açık ve açık bir çözüm str.rstrip.
>>> import re
Bir veya daha fazla sondaki yeni satır karakterini kaldırmak istiyorsanız :
>>> re.sub(r'[\n\r]+$', '', '\nx\r\n')
'\nx'
Newline karakterlerini her yerde kaldırmak istiyorsanız (yalnızca sondaki değil):
>>> re.sub(r'[\n\r]+', '', '\nx\r\n')
'x'
Yalnızca 1-2 sondaki yeni satır karakterleri kaldırmak istiyorsanız (yani \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'
Çoğu insanın burada gerçekten ne istediğini hissediyorum, sondaki yeni satır karakterinin tek bir örneğini kaldırmak ya \r\nda \nbaşka bir şey yok.
>>> 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'
( ?:Yakalamayan bir grup oluşturmaktır.)
(Bu arada, bu iş parçacığı üzerinde tökezleyen başkaları için net olmayan bir şey '...'.rstrip('\n', '').rstrip('\r', '')değildir. str.rstripMümkün olan en fazla karakter dizer, bu nedenle bir dize foo\n\n\nyanlış pozitif sonuç fooverirken, korumak isteyebilirsiniz. tek bir sondaki sıyırdıktan sonra diğer yeni satırlar.)
r'\r?\n$'. Muhtemelen daha verimlidir, çünkü regex motorları alternatifleri optimize etmek için daha zor zamanlara sahiptir. Ayrıca, bunu birçok kez yapacaksanız , ifadenin önüne bir kez daha önemli bir şekilde daha hızlı olacağını (özellikle başka rekullanımlarla karışıyorsanız ) , derlenmiş normal ifade nesnesinin yöntemini re.compilekullanın sub; modül işlevleri Python düzeyindedir ve önce derlenmiş normal ifadeler için bir önbellek kontrol edin (eksikse oluşturma / önbellekleme), ardından eşleşen yöntemi çağırın; bu aramayı atlamak yardımcı olur.
\nDoğrudan eşleştirmeye çalıştığınız için , \Züzerinde kullanmak isteyebilirsiniz $(veya yalnızca eşleştirin \r?$, çünkü $örtük olarak bir dizenin sonundaki yeni satırdan hemen önce eşleşebilir).
>>> ' spacious '.rstrip()
' spacious'
>>> "AABAA".rstrip("A")
'AAB'
>>> "ABBA".rstrip("AB") # both AB and BA are stripped
''
>>> "ABCABBA".rstrip("AB")
'ABC'
"\r\n"Örneğin: ' spacious \n\r\n\r \n\n'.rstrip()üretir' spacious'
Sadece kullan :
line = line.rstrip("\n")
veya
line = line.strip("\n")
Bu karmaşık şeylerden hiçbirine ihtiyacınız yok
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'
Normal ifade ile
s = ''' Hello World
\t\n\r\tHi '''
print(re.sub(r"\s+", "", s), sep='') # \s matches all white spaces
>HelloWorldHi
\ N, \ t, \ r yerine
s.replace('\n', '').replace('\t','').replace('\r','')
>' Hello World Hi '
Normal ifade ile
s = '''Hello World \t\n\r\tHi There'''
regex = re.compile(r'[\n\r\t]')
regex.sub("", s)
>'Hello World Hi There'
Join ile
s = '''Hello World \t\n\r\tHi There'''
' '.join(s.split())
>'Hello World Hi There'
Orada normalde karşılaşmak satır sonları üç tipi vardır: \n, \rve \r\n. Oldukça basit bir düzenli ifade re.sub, yani r"\r?\n?$"hepsini yakalayabilir.
(Ve hepsini yakalamalıyız , değil mi?)
import re
re.sub(r"\r?\n?$", "", the_text, 1)
Son argümanla, chomp'ı bir dereceye kadar taklit ederek, yerine geçen olay sayısını sınırlandırıyoruz. Misal:
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)
... nerede a == b == colduğunu True.
rstrip("\r\n")bir catch-all. Deneyin print(text_2.rstrip('\r\n')).
str.rstrip()sorunu çözdüğü göz önüne alındığında . Hangi ihtiyaçlara sahip olduğunuza bağlıdır. Bu çözüm özellikle Üstelik geçen kaldırmak gerektiğinde durumlar için yapılır "\n", "\r"ya da "\r\n"ancak hepsi değil (birden varsa "\n"dizede). farklı bir dize olan re.sub(r"\r?\n?$", "", text_1, 1)döndürür "hellothere\n\n"ve text_1.rstrip("\r\n")döndürür "hellothere".
str.strip()bir catch-all bazen çok sorun.
Hızla ilgili endişeleriniz varsa (dizelerinizde looong bir listeniz olduğunu varsayalım) ve newline char'ın doğasını biliyorsanız, dize dilimleme aslında rstrip'ten daha hızlıdır. Bunu göstermek için küçük bir test:
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()
Çıktı:
Method 1: 3.92700004578
Method 2: 6.73000001907
method1sadece son karakteri, ne olursa olsun kapalı dorarken ilk çekler, eğer dize sonu istenmeyen karakterler içeriyor ve bazı bulundu yalnızca, onları doğruyor. Lütfen karakterleri kontrol edin ve hedefi test edin ! method2.rstrip()method1
Bu hem windows hem de linux için çalışacaktır (sadece yeniden çözüm arıyorsanız, re sub ile biraz pahalı)
import re
if re.search("(\\r|)\\n$", line):
line = re.sub("(\\r|)\\n$", "", line)
re.searchihtiyacınız olanı kullanıyorsunuz re.sub?
Hepsini yakala:
line = line.rstrip('\r|\n')
rstripdüzenli ifade almaz. "hi|||\n\n".rstrip("\r|\n")döner"hi"