繁体   English   中英

如何读取文本文件的特定部分(Py 3x)

[英]How to read a specific part of a text file (Py 3x)

对于Python,其他问题似乎没有得到解决或没有得到解决。 我试图让它找到关键字“名称”,将位置设置在那里,然后将变量设置为该特定行,然后让它仅将那段文字用作变量。 简而言之,我试图根据始终存在的“名称”或“ HP”在.txt文件中定位一个变量。

我希望这是有道理的...

我尝试使用不同的变量,例如currentplace而不是namePlace但是都namePlace

import os

def savetest():
    save = open("nametest_text.txt", "r")
    print("Do you have a save?")
    conf = input(": ")
    if conf == "y" or conf == "Y" or conf == "Yes" or conf == "yes":
        text = save.read()
        namePlace = text.find("name")
        currentText = namePlace + 7
        save.seek(namePlace)
        nameLine = save.readline()
        username = nameLine[currentText:len(nameLine)]
        print(username)

        hpPlace = text.find("HP")
        currentText = hpPlace + 5
        save.seek(hpPlace)
        hpLine = save.readline()
        playerHP = hpLine[currentText:len(hpLine)]
        print(playerHP)
        os.system("pause")
        save.close()
savetest()

我的文本文件很简单:

name = Wubzy

HP = 100

我希望它打印出nameHP等号后放在等号后的所有内容,而不是nameHP本身。

所以它应该打印

Wubzy
100
Press any key to continue . . .

但它打印

Wubzy


Press any key to continue . . .

使用正则表达式根据模式提取:

'(?:name|HP) = (.*)'

这将捕获在等号后跟nameHP

代码

import re

with open("nametest_text.txt", "r") as f:    
    for line in f:
        m = re.search(r'(?:name|HP) = (.*)', line.strip())
        if m:
            print(m.group(1))

最简单的方法可能是使用str.split()然后在'='字符后打印所有内容:

with open("nametest_text.txt", "r") as f:    
    for line in f:
        if line.strip():
            print(line.strip().split(' = ')[1])

输出:

Wubzy
100

对于正则表达式而言,这看起来是一项不错的工作。 正则表达式可以匹配并捕获文本中的模式,这似乎正是您要尝试的方法。

例如,正则表达式^name\\s*=\\s*(\\w+)$将匹配具有确切文本“ name”,后跟0或多个空格字符,“ =”,然后再包含0或多个字符的行空格字符,然后是一个或多个字母。 它将在最后捕获单词组。

正则表达式^HP\\s*=\\s*(\\d+)$将匹配具有精确文本“ HP”的行,后跟0或多个空格字符,“ =”,然后是0或多个空格字符一个或多个数字。 它将在最后捕获数字组。


# This is the regex library
import re

# This might be easier to use if you're getting more information in the future.
reg_dict = {
    "name": re.compile(r"^name\s*=\s*(\w+)$"),
    "HP": re.compile(r"^HP\s*=\s*(\d+)$")
}


def savetest():
    save = open("nametest_text.txt", "r")
    print("Do you have a save?")
    conf = input(": ")
    # instead of checking each one individually, you can check if conf is
    # within a much smaller set of valid answers
    if conf.lower() in ["y", "yes"]:
        text = save.read()

        # Find the name
        match = reg_dict["name"].search(text)
        # .search will return the first match of the text, or if there are
        # no occurrences, None
        if(match):
            # With match groups, group(0) is the entire match, group(1) is
            # What was captured in the first set of parenthesis
            username = match.group(1)
        else:
            print("The text file does not contain a username.")
            return
        print(username)

        # Find the HP
        match = reg_dict["HP"].search(text)
        if(match):
            player_hp = match.group(1)
        else:
            print("The text file does not contain a HP.")
            return
        print(player_hp)

        # Using system calls to pause output is not a great idea for a 
        # variety of reasons, such as cross OS compatibility
        # Instead of os.system("pause") try
        input("Press enter to continue...")

        save.close()
savetest()

与其尝试创建和解析专有格式(您很可能会在某个时候遇到限制,并且需要更改逻辑和/或文件格式),不如坚持使用随附的众所周知且定义明确的文件格式所需的编写器和解析器,例如yamljsoncfgxml等。

这样可以节省很多痛苦; 请考虑以下包含状态的类的快速示例,该类可以被序列化为键值映射的文件格式(我在这里使用yaml ,但您可以轻松地将其交换为json或其他):

#!/usr/bin/python

import os
import yaml


class GameState:
    def __init__(self, name, **kwargs):
        self.name = name
        self.health = 100

        self.__dict__.update(kwargs)

    @staticmethod
    def from_savegame(path):
        with open(path, 'r') as savegame:
            args = yaml.safe_load(savegame)
            return GameState(**args)

    def save(self, path, overwrite=False):
        if os.path.exists(path) and os.path.isfile(path) and not overwrite:
            raise IOError('Savegame exists; refusing to overwrite.')

        with open(path, 'w') as savegame:
            savegame.write(yaml.dump(self.__dict__))

    def __str__(self):
        return (
            'GameState(\n{}\n)'
            .format(
                '\n'.join([
                    '  {}: {}'.format(k, v)
                    for k, v in self.__dict__.iteritems()
                ]))
        )

示例性地使用此简单类:

SAVEGAMEFILE = 'savegame_01.yml'

new_gs = GameState(name='jbndlr')
print(new_gs)
new_gs.health = 98
print(new_gs)
new_gs.save(SAVEGAMEFILE, overwrite=True)

old_gs = GameState.from_savegame(SAVEGAMEFILE)
print(old_gs)

...产量:

GameState(
  health: 100
  name: jbndlr
)
GameState(
  health: 98
  name: jbndlr
)
GameState(
  health: 98
  name: jbndlr
)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM