改行文字列の最後の文字を削除するPerl のchomp
関数に相当する Python は何ですか?
27 に答える
メソッドを試してくださいrstrip()
(ドキュメントPython 2およびPython 3を参照)
>>> 'test string\n'.rstrip()
'test string'
Python の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 '
に加えてrstrip()
、 と のメソッドもありstrip()
ますlstrip()
。以下に、それらの 3 つの例を示します。
>>> 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'
そして、改行文字を末尾に付けずに行を取得する「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"
rstrip は、文字列を変更しないため、Perl の chomp() とまったく同じように動作しないことに注意してください。つまり、Perl では次のようになります。
$x="a\n";
chomp $x
$x
となります"a"
。
しかしPythonでは:
x="a\n"
x.rstrip()
x
の値がまだ であることを意味します"a\n"
。Evenx=x.rstrip()
は常に同じ結果になるとは限りません。多くても 1 つの改行ではなく、文字列の末尾からすべての空白を削除するからです。
私はこのようなものを使うかもしれません:
import os
s = s.rstrip(os.linesep)
問題rstrip("\n")
は、行区切り記号が移植可能であることを確認する必要があることだと思います。(一部の時代遅れのシステムは使用すると噂されています"\r\n"
)。もう1つの落とし穴は、rstrip
繰り返される空白を取り除くことです。うまくいけばos.linesep
、適切な文字が含まれます。上記は私のために働きます。
を使用できますline = line.rstrip('\n')
。これにより、1 つだけでなく、文字列の末尾からすべての改行が削除されます。
s = s.rstrip()
文字列の末尾にあるすべての改行を削除しますs
。rstrip
元の文字列を変更するのではなく、新しい文字列を返すため、割り当てが必要です。
これは、"\n" 行末記号に対して perl の chomp を正確に複製します (配列での動作を除く):
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 を考慮に入れます)
"line 1\nline 2\r\n...".replace('\n', '').replace('\r', '')
>>> 'line 1line 2...'
または、いつでも正規表現でオタクになることができます
rstrip は、非常に多くのレベルで chomp と同じことを行いません。http://perldoc.perl.org/functions/chomp.htmlを読んで、chomp が非常に複雑であることを確認してください。
ただし、私の主なポイントは、chomp は最大で 1 つの行末を削除するのに対し、rstrip は可能な限り多くの行末を削除するということです。
ここでは、すべての改行を削除する rstrip を確認できます。
>>> 'foo\n\n'.rstrip(os.linesep)
'foo'
次のように、re.sub を使用すると、Perl の典型的な chomp の使用法をより厳密に近似できます。
>>> re.sub(os.linesep + r'\Z','','foo\n\n')
'foo\n'
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)
注意"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")
マイクが上で言ったように、代わりに使用してください。
I don't program in Python, but I came across an FAQ at python.org advocating S.rstrip("\r\n") for python 2.2 or later.
特殊なケースの回避策:
改行文字が最後の文字である場合 (ほとんどのファイル入力の場合と同様)、コレクション内の任意の要素に対して、次のようにインデックスを付けることができます。
foobar= foobar[:-1]
改行文字を切り出します。
>>> ' spacious '.rstrip()
' spacious'
>>> "AABAA".rstrip("A")
'AAB'
>>> "ABBA".rstrip("AB") # both AB and BA are stripped
''
>>> "ABCABBA".rstrip("AB")
'ABC'
使用するだけです:
line = line.rstrip("\n")
また
line = line.strip("\n")
この複雑なものは必要ありません
\n
通常遭遇する行末には、 、 、の 3 種類があり\r
ます\r\n
。のかなり単純な正規表現re.sub
、つまりr"\r?\n?$"
は、それらすべてをキャッチできます。
(そして、私たちはすべてを捕まえなければなりません、私は正しいですか?)
import re
re.sub(r"\r?\n?$", "", the_text, 1)
最後の引数を使用して、置き換えられる出現回数を 1 回に制限し、chomp をある程度模倣します。例:
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 よりも高速です。これを説明するための小さなテスト:
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