Python分割文本文件并保留换行符

4

我正在尝试将一个文本文件拆分成单词,\n 被视为一个单词。

我的输入是这个文本文件:

War and Peace

by Leo Tolstoy/Tolstoi

我希望您能输出类似以下格式的列表: ```` ````
['War','and','Peace','\n','\n','by','Leo','Tolstoy/Tolstoi']

使用 .split() 我得到了这个结果:
['War', 'and', 'Peace\n\nby', 'Leo', 'Tolstoy/Tolstoi']

所以我开始编写程序,在单词后将 \n 作为单独的条目添加,代码如下:
for oldword in text:
counter = 0
newword = oldword
while "\n" in newword:
    newword = newword.replace("\n","",1)
    counter += 1

text[text.index(oldword)] = newword

while counter > 0:
    text.insert(text.index(newword)+1, "\n")
    counter -= 1

然而,程序似乎在 counter -= 1 这一行卡住了,我真的想不出为什么。
注意:我意识到如果这样做可以成功,结果将是 ['Peaceby',"\n","\n"];这是另一个待解决的问题。

1
你的格式有问题。不确定修复方法是什么。第2行和第3行应该缩进到 for oldword in text: 下面吗? - Eugene K
我怀疑你得到的是 'Peace\n\nby' - Padraic Cunningham
如果您使用split(' '),就会这样做。也许这就是 OP 的意思。 - tdelaney
所有代码都缩进在 for 循环下面,在复制粘贴时丢失了。我使用了 split(" ") 来避免丢失换行符。 - Christopher Riches
如果你用空格替换 "\n",那么 split(" ") 就可以让你接近你想要的结果。它可能包含一些空元素,你需要将它们排除掉。 - user4171906
4个回答

7

您无需采用如此复杂的方法,只需使用正则表达式和re.findall()函数即可找到所有单词和换行符:

>>> s="""War and Peace
... 
... by Leo Tolstoy/Tolstoi"""
>>> 
>>> re.findall(r'\S+|\n',s)
['War', 'and', 'Peace', '\n', '\n', 'by', 'Leo', 'Tolstoy/Tolstoi']

'\S+|\n'将匹配长度为1或更多的所有非空白字符组合(\S+)或换行符(\n)。

如果您想从文件中获取文本,可以执行以下操作:

with open('file_name') as f:
     re.findall(r'\S+|\n',f.read())

了解更多关于正则表达式的内容,请访问http://www.regular-expressions.info/


看起来很棒,但我不明白你刚才说的话,也不知道这如何适用于代码。 - Christopher Riches
1
好的,谢谢,我解决了。不过,我失去了所有标点符号,比如撇号和托尔斯泰和托尔斯托伊之间的“/”符号。 - Christopher Riches
@ChristopherRiches 抱歉,我更新了正则表达式,请检查编辑。 - Mazdak
@msw 我不这么认为,也许还有其他方法,但我认为这是非常直接的方法,正如你所知道的“美丽胜于丑陋”、“显式优于隐式”、“简单胜于复杂”、“复杂胜于混乱”。 - Mazdak
@Kasramvd 谢谢,现在它可以工作了。我没有时间在正则表达式网站上搜索,所以你能否请详细解释一下 (r'\S+|\n') 的含义? - Christopher Riches
@ChristopherRiches 欢迎,我在回答中已经解释了,\S将匹配单个非空格字符,例如字母字符或标点符号,修饰符+会使正则表达式引擎匹配其前面的标记1次或多次,而|是逻辑OR,这意味着子字符串将是\S+\n - Mazdak

0

当你读取文件时,可以逐行处理,这样可以逐行拆分并适当处理换行符:

>>> [word for line in inputFile for word in line.rstrip('\n').split() + ['\n']]
['War', 'and', 'Peace', '\n', '\n', 'by', 'Leo', 'Tolstoy/Tolstoi', '\n']

简单的解释:
  • for line in inputFile:对于输入文件中的每一行
  • for word in line.rstrip('\n').split() + ['\n']:去掉换行符并将该行分割,然后将新行作为一个单独的元素添加回去

请注意,如果您使用没有分隔符的split(),则实际上不需要rstrip('\n')

您可以将这些确切的表达式用作循环,而不是列表推导:

result = []
for line in inputFile:
    for word in line.rstrip('\n').split():
        result.append(word)
    result.append('\n')
print(result)

这将产生相同的输出:

['War', 'and', 'Peace', '\n', '\n', 'by', 'Leo', 'Tolstoy/Tolstoi', '\n']

0

这是另一种变体:

with open('data.txt') as fobj:
    for line in fobj:
        words.extend(line.split())
        words.append('\n')

它在所有空格(包括制表符)处分割单词。


0
为了摆脱\n字符并成功地按空格拆分以获取列表的每个索引作为不同的单词,您可以首先使用string.replace('\n\n', ' ')替换\n\n的值,并将其等于一个新字符串,然后按空格拆分...newString.split(' ')

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接