chomp
改行である場合に文字列の最後の文字を削除するPerlの関数に相当するPythonの機能は何ですか?
open()
の適切な「newline = ...」パラメーターを含むファイルを忘れたことが原因である場合(ユニバーサル改行サポート)、明示的に削除する必要がない場合があります。
chomp
改行である場合に文字列の最後の文字を削除するPerlの関数に相当するPythonの機能は何ですか?
open()
の適切な「newline = ...」パラメーターを含むファイルを忘れたことが原因である場合(ユニバーサル改行サポート)、明示的に削除する必要がない場合があります。
回答:
メソッドを試すrstrip()
(doc Python 2およびPython 3を参照)
>>> 'test string\n'.rstrip()
'test string'
Pythonのrstrip()
メソッドは、Perlのように改行を1つだけではなく、デフォルトですべての種類の末尾の空白を削除します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'
\n
Unixと同じように改行を使用します。(OS X以前は、MacOS \r
は行区切り文字として使用していましたが、10年前に終了しました。)
.strip()
文字列を変更しません(おそらく不変文字列と関係があります)。コマンドラインにない場合は、次のようにする必要があります"string = string.strip()"
そして、末尾の改行文字なしで行を取得する「pythonic」方法は、splitlines()だと思います。
>>> text = "line 1\nline 2\r\nline 3\nline 4"
>>> text.splitlines()
['line 1', 'line 2', 'line 3', 'line 4']
行末(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'
rstripのパラメーターとして「\ r \ n」を使用すると、「\ r」または「\ n」の末尾の組み合わせがすべて取り除かれます。それが上記の3つのケースすべてで機能する理由です。
このニュアンスはまれなケースで重要です。たとえば、HL7メッセージを含むテキストファイルを処理する必要がありました。HL7標準では、EOL文字として末尾の「\ r」が必要です。このメッセージを使用していたWindowsマシンには、独自の「\ r \ n」EOL文字が追加されていました。したがって、各行の終わりは「\ r \ r \ n」のようになりました。rstrip( '\ r \ n')を使用すると、 '\ r \ r \ n'全体が削除されますが、これは私が望んでいたものではありません。その場合、代わりに最後の2つの文字を切り捨てました。
Perlのchomp
関数とは異なり、これは文字列の最後にある1つだけでなく、指定されたすべての文字を削除することに注意してください。
>>> "Hello\n\n\n".rstrip("\n")
"Hello"
os.linesep
現在のOSのEOLシーケンスを含むもあります。
\n
およびand\r
私はこのようなものを使うかもしれません:
import os
s = s.rstrip(os.linesep)
問題rstrip("\n")
は、おそらく行区切り文字が移植可能であることを確認したいことだと思います。(一部の時代遅れのシステムはを使用すると噂されています"\r\n"
)。他の落とし穴は、rstrip
繰り返される空白を取り除くことです。うまくいけばos.linesep
、適切な文字が含まれます。上記は私のために働きます。
rstrip('\r\n')
と同じrstrip()
であり、引数にあるすべての文字を取り除くのでまだ機能します。
"line 1\nline 2\r\n...".replace('\n', '').replace('\r', '')
>>> 'line 1line 2...'
または、正規表現でいつでもマニアックになることができます:)
楽しんで!
.replace('\n|\r', '')
ですか?
import re
re.sub('\n|\r', '', '\nx\n\r\n')
==> を使用することはほんの小さな変更'x'
です。
あなたはストリップを使うことができます:
line = line.strip()
デモ:
>>> "\n\n hello world \n\n".strip()
'hello world'
rstripは、非常に多くのレベルで、chompと同じことを行いません。http://perldoc.perl.org/functions/chomp.htmlをお読みくださいを、chompが非常に複雑であることを確認してください。
ただし、私の主なポイントは、chompは最大1行の行末を削除するのに対し、rstripはできる限り多くの行を削除するということです。
ここでは、rstripがすべての改行を削除しているのを確認できます。
>>> 'foo\n\n'.rstrip(os.linesep)
'foo'
次のように、re.subを使用すると、典型的なPerlチョンプの使用法に非常に近づくことができます。
>>> re.sub(os.linesep + r'\Z','','foo\n\n')
'foo\n'
注意"foo".rstrip(os.linesep)
:Pythonが実行されているプラットフォームの改行文字のみが表示されます。たとえば、LinuxでWindowsファイルの行を次々に変更しているとします。
$ 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")
マイクは上記の言うように、代わりに。
chomp
です。
Pythonのドキュメントの例では、単にを使用していline.strip()
ます。
Perlのchomp
関数は、実際にそこにある場合にのみ、文字列の最後から1つの改行シーケンスを削除します。
これが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)
import re
r_unwanted = re.compile("[\n\t\r]")
r_unwanted.sub("", your_text)
ファイルオブジェクトからチョップされていない行を取得する方法と並行して、イテレータでチョップされた行を取得できると便利です。これは次のコードで実行できます。
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
and map
(itertools.imap
Py2の場合)を使用すると、この作業をCレイヤーにプッシュして、Pythonレベルジェネレーターコードを回避できます(そのため、I / Oオーバーヘッドが小さいゲインをマスクする可能性が高いですが、少し高速で実行されます)for line in map(operator.methodcaller('rstrip', '\r\n'), infile):
。それはまだとして因数分解できますdef chomped_lines(it): return map(operator.methodcaller('rstrip', '\r\n'), it)
。
perl's chompには完璧なアナログがないようです。特に、rstripはのような複数文字の改行区切り文字を処理できません\r\n
。ただし、splitlinesはここで指摘されているように機能します。別の質問に対する私の回答に続き、結合と分割線を組み合わせて、文字列からすべての改行を削除/置換できますs
。
''.join(s.splitlines())
次の例では、末尾の改行を1つだけ削除します(私が信じているように)。分割線へTrue
のkeepends
引数として渡しても、区切り文字は保持されます。次に、splitlinesが再び呼び出され、最後の「行」の区切り文字が削除されます。
def chomp(s):
if len(s):
lines = s.splitlines(True)
last = lines.pop()
return ''.join(lines + last.splitlines())
else:
return ''
私は以前に別の回答のコメントで投稿したものからの私の正規表現ベースの回答を泡立たせています。を使用することre
は、この問題の明確な解決策であると考えていstr.rstrip
ます。
>>> import re
1つ以上の末尾の改行文字を削除する場合:
>>> 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'
私はほとんどの人は本当にここに何をしたい気持ちを持って、単に削除しないことである1改行文字の発生を、いずれか\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
あなたが保存したかったかもしれないのに対し、末尾の1行を削除した後の他の改行。)
r'\r?\n$'
。正規表現エンジンは代替を最適化するのに苦労するため、おそらくより効率的です。また、これを何度も実行する場合は、最初に式をre
使用すると(特に他の用途と混ざっている場合)re.compile
、式が大幅に速くなりsub
、コンパイルされた正規表現オブジェクトのメソッドを使用することに注意してください。モジュール関数はPythonレベルであり、まずコンパイルされた正規表現のキャッシュをチェックし(見つからない場合は作成/キャッシュ)、次に一致するメソッドを呼び出します。そのルックアップをスキップすると役立ちます。
\n
直接一致させようとしているので、\Z
over を使用することもできます$
(または、文字列の末尾の改行の直前で暗黙的に一致できる\r?$
ため、単にmatch を使用し$
ます)。
>>> ' spacious '.rstrip()
' spacious'
>>> "AABAA".rstrip("A")
'AAB'
>>> "ABBA".rstrip("AB") # both AB and BA are stripped
''
>>> "ABCABBA".rstrip("AB")
'ABC'
"\r\n"
例:' spacious \n\r\n\r \n\n'.rstrip()
生産' spacious'
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'
正規表現を使って
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 '
正規表現を使って
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)
最後の議論では、置き換えられる出現の数を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 == c
ですTrue
。
rstrip("\r\n")
キャッチオールです。お試しくださいprint(text_2.rstrip('\r\n'))
。
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()
は、それがキャッチオールであることが時々非常に問題です。
速度が気になり(文字列のリストが間違っているなど)、改行文字の性質がわかっている場合、実際には文字列のスライスは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
method1
れmethod2
ているかどうかに関係なく、最後の文字を切り落としているだけです.rstrip()
。の文字のチェックを実装してmethod1
、アギンをテストしてください!