无法删除 python 中文本文件中的换行符
Unable to remove line breaks in a text file in python
冒着名誉扫地的风险,我不知道还能做什么。我的文件没有显示任何隐藏字符,我已经尝试了所有我能想到的 .replace 和 .strip。我的文件是 UTF-8 编码的,我使用的是 python/3.6.1
我有一个格式为:
的文件
>header1
AAAAAAAA
TTTTTTTT
CCCCCCCC
GGGGGGGG
>header2
CCCCCC
TTTTTT
GGGGGG
AAAAAA
我试图从文件末尾删除换行符,使每一行成为一个连续的字符串。 (这个文件实际上有数千行)。
我的代码是多余的,因为我输入了我能想到的所有内容来删除换行符:
fref = open(ref)
for line in fref:
sequence = 0
header = 0
if line.startswith('>'):
header = ''.join(line.splitlines())
print(header)
else:
sequence = line.strip("\n").strip("\r")
sequence = line.replace('\n', ' ').replace('\r', '').replace(' ', '').replace('\t', '')
print(len(sequence))
输出为:
>header1
8
8
8
8
>header2
6
6
6
6
但是如果我手动进入并删除行尾以使其成为连续字符串,它会将其显示为全等字符串。
预期输出:
>header1
32
>header2
24
在此先感谢您的帮助,
丹尼斯
根据我对你问题的理解,你可能会喜欢这样的内容:
请注意序列是如何在循环的多个迭代步骤上构建的,因为您希望组合多行。
with open(ref) as f:
sequence = "" # reset sequence
header = None
for line in f:
if line.startswith('>'):
if header:
print(header) # print last header
print(len(sequence)) # print last sequence
sequence = "" # reset sequence
header = line[1:] # store header
else:
sequence += line.rstrip() # append line to sequence
有几种方法可以解析这种输入。在所有情况下,我建议将 open 和 print side-effects 隔离在函数之外,您可以通过单元测试说服自己正确的行为。
您可以遍历每一行并分别处理空行和 end-of-file 的情况。在这里,我使用 yield 语句 return 值:
def parse(infile):
for line in infile:
if line.startswith(">"):
total = 0
yield line.strip()
elif not line.strip():
yield total
else:
total += len(line.strip())
if line.strip():
yield total
def test_parse(func):
with open("input.txt") as infile:
assert list(parse(infile)) == [
">header1",
32,
">header2",
24,
]
或者,您可以同时处理空行和 end-of-file。在这里,我使用了一个输出数组,我在其中附加了 headers 和 totals:
def parse(infile):
output = []
while True:
line = infile.readline()
if line.startswith(">"):
total = 0
header = line.strip()
elif line and line.strip():
total += len(line.strip())
else:
output.append(header)
output.append(total)
if not line:
break
return output
def test_parse(func):
with open("input.txt") as infile:
assert parse(infile) == [
">header1",
32,
">header2",
24,
]
或者,您也可以将整个输入文件拆分为 empty-line-separated 块并独立解析它们。在这里,我使用一个输出流来写入输出;在生产中,您可以传递 sys.stdout 流,例如:
import re
def parse(infile, outfile):
content = infile.read()
for block in re.split(r"\r?\n\r?\n", content):
header, *lines = re.split(r"\s+", block)
total = sum(len(line) for line in lines)
outfile.write("{header}\n{total}\n".format(
header=header,
total=total,
))
from io import StringIO
def test_parse(func):
with open("/tmp/a.txt") as infile:
outfile = StringIO()
parse(infile, outfile)
outfile.seek(0)
assert outfile.readlines() == [
">header1\n",
"32\n",
">header2\n",
"24\n",
]
请注意,为了简洁起见,我的测试使用 open("input.txt") 但实际上我建议传递一个 StringIO(...) 实例而不是更容易地看到正在测试的输入,以避免命中文件系统并使测试更快。
冒着名誉扫地的风险,我不知道还能做什么。我的文件没有显示任何隐藏字符,我已经尝试了所有我能想到的 .replace 和 .strip。我的文件是 UTF-8 编码的,我使用的是 python/3.6.1 我有一个格式为:
的文件 >header1
AAAAAAAA
TTTTTTTT
CCCCCCCC
GGGGGGGG
>header2
CCCCCC
TTTTTT
GGGGGG
AAAAAA
我试图从文件末尾删除换行符,使每一行成为一个连续的字符串。 (这个文件实际上有数千行)。 我的代码是多余的,因为我输入了我能想到的所有内容来删除换行符:
fref = open(ref)
for line in fref:
sequence = 0
header = 0
if line.startswith('>'):
header = ''.join(line.splitlines())
print(header)
else:
sequence = line.strip("\n").strip("\r")
sequence = line.replace('\n', ' ').replace('\r', '').replace(' ', '').replace('\t', '')
print(len(sequence))
输出为:
>header1
8
8
8
8
>header2
6
6
6
6
但是如果我手动进入并删除行尾以使其成为连续字符串,它会将其显示为全等字符串。
预期输出:
>header1
32
>header2
24
在此先感谢您的帮助, 丹尼斯
根据我对你问题的理解,你可能会喜欢这样的内容: 请注意序列是如何在循环的多个迭代步骤上构建的,因为您希望组合多行。
with open(ref) as f:
sequence = "" # reset sequence
header = None
for line in f:
if line.startswith('>'):
if header:
print(header) # print last header
print(len(sequence)) # print last sequence
sequence = "" # reset sequence
header = line[1:] # store header
else:
sequence += line.rstrip() # append line to sequence
有几种方法可以解析这种输入。在所有情况下,我建议将 open 和 print side-effects 隔离在函数之外,您可以通过单元测试说服自己正确的行为。
您可以遍历每一行并分别处理空行和 end-of-file 的情况。在这里,我使用 yield 语句 return 值:
def parse(infile):
for line in infile:
if line.startswith(">"):
total = 0
yield line.strip()
elif not line.strip():
yield total
else:
total += len(line.strip())
if line.strip():
yield total
def test_parse(func):
with open("input.txt") as infile:
assert list(parse(infile)) == [
">header1",
32,
">header2",
24,
]
或者,您可以同时处理空行和 end-of-file。在这里,我使用了一个输出数组,我在其中附加了 headers 和 totals:
def parse(infile):
output = []
while True:
line = infile.readline()
if line.startswith(">"):
total = 0
header = line.strip()
elif line and line.strip():
total += len(line.strip())
else:
output.append(header)
output.append(total)
if not line:
break
return output
def test_parse(func):
with open("input.txt") as infile:
assert parse(infile) == [
">header1",
32,
">header2",
24,
]
或者,您也可以将整个输入文件拆分为 empty-line-separated 块并独立解析它们。在这里,我使用一个输出流来写入输出;在生产中,您可以传递 sys.stdout 流,例如:
import re
def parse(infile, outfile):
content = infile.read()
for block in re.split(r"\r?\n\r?\n", content):
header, *lines = re.split(r"\s+", block)
total = sum(len(line) for line in lines)
outfile.write("{header}\n{total}\n".format(
header=header,
total=total,
))
from io import StringIO
def test_parse(func):
with open("/tmp/a.txt") as infile:
outfile = StringIO()
parse(infile, outfile)
outfile.seek(0)
assert outfile.readlines() == [
">header1\n",
"32\n",
">header2\n",
"24\n",
]
请注意,为了简洁起见,我的测试使用 open("input.txt") 但实际上我建议传递一个 StringIO(...) 实例而不是更容易地看到正在测试的输入,以避免命中文件系统并使测试更快。