【问题标题】:Python: How to replace the last word of a line from a text file?Python:如何替换文本文件中一行的最后一个单词?
【发布时间】:2015-07-11 07:11:39
【问题描述】:

如何从已加载到 Python 中的文本文件的所有行中替换特定行的最后一个单词?我知道如果我想以列表的形式访问它,我会使用 [-1] 来表示特定的行,但我不知道如何将它作为字符串来访问。文本文件的一个例子是:

A I'm at the shop with Bill.
B I'm at the shop with Sarah. 
C I'm at the shop with nobody. 
D I'm at the shop with Cameron.

【问题讨论】:

  • line.split()[-1] 给你一串单词的最后一个单词

标签: python


【解决方案1】:

如果您想要更强大的编辑选项,Regex 是您的朋友。

import re
pattern = re.compile(r'\w*(\W*)$')  # Matches the last word, and captures any remaining non-word characters
                                    # so we don't lose punctuation. This will includes newline chars.

line_num = 2 # The line number we want to operate on.
new_name = 'Steve' # Who are we at the shops with? Not Allan.

with open('shopping_friends.txt') as f:
    lines = f.readlines()
    lines[line_num] = re.sub(pattern, new_name + r'\1', lines[line_num]) 
    # substitue the last word for your friend's name, keeping punctuation after it.
    # Now do something with your modified data here

【讨论】:

  • 是的。保留标点符号和空格很重要,正则表达式比尝试替换最后一个单词更容易,而不用使用字符串函数干扰行的其余部分。
【解决方案2】:

请检查一下,不是 100% pythonic,更多的是为了概述

file_text = '''I'm at the shop with Bill.
I'm at the shop with Sarah. 
I'm at the shop with nobody. 
I'm at the shop with Cameron.
I'm at the shop with nobody.'''

def rep_last_word_line(textin, search_for, replace_with, line_nr):
    if (isinstance(textin,str)):
        textin = textin.splitlines()
    else:
        # remove enline from all lines - just in case
        textin = [ln.replace('\n', ' ').replace('\r', '') for ln in textin]
    if (textin[line_nr] != None):
        line = textin[line_nr].replace('\n', ' ').replace('\r', '')

        splited_line = line.split()
        last_word = splited_line[-1]
        if (last_word[0:len(search_for)] == search_for):
            splited_line[-1] = last_word.replace(search_for,replace_with)
        textin[line_nr] = ' '.join(splited_line)

        return '\r\n'.join(textin)

print rep_last_word_line(file_text,'nobody','Steve',2) 
print '='*80
print rep_last_word_line(file_text,'nobody','Steve',4) 
print '='*80
# read content from file

f = open('in.txt','r')
# file_text = f.read().splitlines() # read text and then use str.splitlines to split line withoud endline character
file_text = f.readlines() # this will keep the endline character 
print rep_last_word_line(file_text,'nobody','Steve',2) 

【讨论】:

    【解决方案3】:

    如果你有空行,你可能想试试splitlines()

    lines = your_text.splitlines()
    lastword = lines[line_to_replace].split()[-1]
    lines[line_to_replace] = lines[line_to_replace].replace(lastword, word_to_replace_with) 
    

    请记住,您的更改现在位于 lines 而不是 your_text,因此如果您希望您的更改持续存在,则必须改为写出 lines

    with open('shops.txt', 'w') as s:
        for l in lines:
            s.write(l)
    

    【讨论】:

    • “写出lines”是什么意思?
    • 当您拆分your_text 时,它被存储在一个新对象lines 中。 lines你可以随便用,但是你的原文your_text不会被修改。
    • 我明白了。那我该如何修改呢?
    • lines 对象将是shops.txt 文件的更新版本。您可以简单地用lines 中的数据覆盖原始文件。如果shops.txt 文件真的很大,那么您将不得不切换到更复杂的解决方案。
    • 我在编辑后的帖子中这样做的方式,我试图覆盖它,但它只是用单个编辑的行覆盖了整个文件。
    【解决方案4】:

    假设你有一个文件“example.txt”:

    with open("example.txt") as myfile:
       mylines = list(myfile)
       lastword = mylines[2].split()[-1]
       mylines[2] = mylines[2].replace(lastword,"Steve.") 
    

    (编辑:修正了一个错误......假设第 3 行,他的意思是人类风格计数而不是第零索引)

    (注意 with 行返回一个文件对象,即使 myfile 的长度小于 3,它也会自动关闭;这个文件对象还提供了一个迭代器,然后它会被转换为一个直列表,所以你可以选择一个特定的行。)

    【讨论】:

    • 这很有趣,还有什么比 Pythonic 的 - 像 list(myfile) 或 myfile.readlines 函数那样的类型转换?
    • 我认为 myfiles.readlines 函数更 Pythonic。我认为 Typecasting 非常罕见,而 readlines() 方法正是出于这个特定原因。
    • 这个解决方案可以很好地处理 OP 数据,但是对于像“I'm at the shop with Steve and Steve”这样的字符串会失败
    • stackoverflow.com/questions/23958198/… 涵盖了性能等方面的问题。(但我并没有真正看到任何明确的论据)......还有一个链接被认为是愚蠢的 readlines
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-06-11
    • 2022-11-23
    • 2015-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-15
    相关资源
    最近更新 更多