V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
zhuzhuaini
V2EX  ›  Python

Python 读取 TXT 如何按照关键行提取内容

  •  
  •   zhuzhuaini · 2021-01-06 15:21:46 +08:00 · 2806 次点击
    这是一个创建于 1401 天前的主题,其中的信息可能已经有所发展或是发生改变。

    比如我有一个文本 A.txt;内容为:
    [测试]
    你好
    你很好
    [正式]
    我好
    我很好

    我想用 Python 读取这个文本 并且呢 把"[测试]"下面的两行自动放入一个变量当中,把"[正式]"下面的内容放入另外一个变量中,这个"测试"和"正式"可以固定预先写死,想问下有哪些实现方式,谢谢

    26 条回复    2021-01-07 11:45:28 +08:00
    mckelvin
        1
    mckelvin  
       2021-01-06 15:40:22 +08:00   ❤️ 1
    建议不要自己编造出一个新的配置格式然后自己做解析,如果你使用现成格式的话就不用考虑这些问题。
    现成的格式可以是 yaml, json, ini, toml, ...
    zhuzhuaini
        2
    zhuzhuaini  
    OP
       2021-01-06 15:50:08 +08:00
    @mckelvin 我刚刚想到用 ini 了 但是 ini 似乎只能读取类似键值对的形式 想直接读取测试下面的所有内容似乎不行 他似乎需要 XXX=YYY 然后通过 XXX 去读取 YYY 这样
    0DBBFF
        3
    0DBBFF  
       2021-01-06 16:06:16 +08:00   ❤️ 1
    是我没看明白还是太简单,直接打开文件读不就行了,最多加点判断条件
    jdhao
        4
    jdhao  
       2021-01-06 16:11:23 +08:00 via Android   ❤️ 1
    直接循环读取文本行解析就行了,难点在哪
    TimePPT
        5
    TimePPT  
       2021-01-06 16:12:46 +08:00   ❤️ 1
    json 不好么
    [{'测试': ['你好','你很好']}, {'正式': ['我好','我很好']}]
    bytesfold
        6
    bytesfold  
       2021-01-06 16:14:16 +08:00   ❤️ 1
    deque,Python Cookbook 第一章 1.3 节
    xiaolinjia
        7
    xiaolinjia  
       2021-01-06 16:16:38 +08:00   ❤️ 2
    你需要的是配置文件的格式,然后用 python 自带的 ConfigParser 模块去读就行了。
    Jackeriss
        8
    Jackeriss  
       2021-01-06 16:18:27 +08:00 via iPhone   ❤️ 1
    用正则不就可以了吗?
    zhuzhuaini
        9
    zhuzhuaini  
    OP
       2021-01-06 16:20:00 +08:00
    @jdhao 难点在于 怎么把两个[]中间的内容放入一个变量中
    leebin
        10
    leebin  
       2021-01-06 16:25:18 +08:00   ❤️ 1
    正常来讲像上面说的用正常的格式去存储就行,非要解析当前这种文本的话,按行读取,用正则匹配,读取到一个[]后,新建一个变量,把读到下一个[]前的内容存到这个变量中就行。不知道这样是否符合你想做的事
    zhuzhuaini
        11
    zhuzhuaini  
    OP
       2021-01-06 16:29:17 +08:00
    @leebin 听起来靠谱...我琢磨下,,,其实我目前所做的事情是这样的,我有一个 TXT,里面有 8 个[],我写了个 GUI,里面有 8 个文本框 我想把这 8 个[]下面的内容 放入这 8 个文本框里面,然后我自由的修改文本框里的内容,然后还能保存,保存的格式就是刚刚说的[]下面然后内容,这样方便下一次的读取和修改,,,不知道大佬有没有更简单的实现方案
    0DBBFF
        12
    0DBBFF  
       2021-01-06 16:33:13 +08:00   ❤️ 1
    @zhuzhuaini

    ```
    import os

    testArr = []
    formalArr = []

    rs = os.path.exists('./test.txt')
    if rs:
    file_handler = open('./test.txt', mode='r',encoding='utf-8')
    contents = file_handler.readlines()
    for line in contents:
    line = line.strip('\n')
    if'[测试]'==line:
    isTest =True
    continue

    if'[正式]'==line:
    isTest =False
    continue

    if isTest:
    testArr.append(line)
    else:
    formalArr.append(line)

    print(testArr)
    print(formalArr)
    ```

    随便写了下,如果有好几个[],isTest 改成个数字或者字符串,下面判断往对应的列表里放就行了
    0DBBFF
        13
    0DBBFF  
       2021-01-06 16:34:51 +08:00   ❤️ 1
    python 的短板哈哈,格式乱了,不过应该能看懂吧..
    lpts007
        14
    lpts007  
       2021-01-06 16:36:35 +08:00 via Android   ❤️ 1
    能问下你为什么要把它存进一个变量里面吗
    leebin
        15
    leebin  
       2021-01-06 16:38:32 +08:00   ❤️ 1
    @zhuzhuaini 简单的话你就用 json 就行,直接操作字典结构,Python 的 json 包里序列化等函数都是现成的
    Osk
        16
    Osk  
       2021-01-06 16:50:08 +08:00 via Android   ❤️ 1
    python 自带的 ini 解析是支持你的这种格式的,印象中我之前用过,文档里有写
    Osk
        17
    Osk  
       2021-01-06 16:51:28 +08:00 via Android   ❤️ 3
    import ConfigParser

    cf = ConfigParser.ConfigParser(allow_no_value=True)
    lpts007
        18
    lpts007  
       2021-01-06 16:56:12 +08:00 via Android   ❤️ 1
    @zhuzhuaini 那我文本框里面填了“[测试]”,系统是不是就出 bug 了

    所以还是 X-Y 问题
    oyasumi
        19
    oyasumi  
       2021-01-06 16:56:39 +08:00 via Android   ❤️ 1
    正则表达式
    CallMeReznov
        20
    CallMeReznov  
       2021-01-06 16:57:58 +08:00   ❤️ 1
    这不就是 ConfigParser 该干的事吗。。。
    saulshao
        21
    saulshao  
       2021-01-06 16:58:01 +08:00   ❤️ 1
    17# 给出了一个完整的解决方案,就照他说的干就行了
    zhuzhuaini
        22
    zhuzhuaini  
    OP
       2021-01-06 17:05:03 +08:00
    @0DBBFF 感谢!我可以琢磨下 应该能看懂
    @lpts007 存变量里是为了每个文本框都去显示对应变量里的值....如果文本框填了的话,确实会出 bug,但是是我自己来修改这个内容 所以我避免掉这个问题即可
    @leebin 好的 我看下 感谢
    @Osk 了解了 现在我通过大家的回复看到了很多的解决方案,我都去试试找一个最方便的
    @saulshao 好的 !
    @CallMeReznov configparser 我之前试了下 发现他只能读取键值对里的值,无法获取整块内容,而我的格式正好不是键值对的形式 17 楼给了一个方案,我先试下
    guhuisec
        23
    guhuisec  
       2021-01-06 17:17:23 +08:00   ❤️ 1
    with open("/Users/yx/PycharmProjects/question/a.txt") as fr:
    items=fr.readlines()

    find={ "[测试]":[],"[正式]":[],}
    def get(some,store):
    if items[i].strip()==some and i+1<len(items):
    for v in items[i+1:]:
    if v[0]!='[':
    store.append(v.strip())
    for i in range(len(items)):
    if items[i].strip() in list(find.keys()):
    get(items[i].strip(),find[items[i].strip()])
    guhuisec
        24
    guhuisec  
       2021-01-06 17:20:22 +08:00   ❤️ 1
    def get(some, store):
    if items[i].strip() == some and i + 1 < len(items):
    for v in items[i + 1:]:
    if v[0] != '[':
    store.append(v.strip())

    with open("/Users/yx/PycharmProjects/question/a.txt") as fr:
    items=fr.readlines()
    for i in range(len(items)):
    if items[i].strip() in list(find.keys()):
    get(items[i].strip(),find[items[i].strip()])
    yaoweilei
        25
    yaoweilei  
       2021-01-07 10:09:36 +08:00   ❤️ 1
    [root@localhost tmp]# cat ini.ini
    [test1]
    key1=value
    key2

    [test2]
    key3=value3
    key4
    [root@localhost tmp]# cat test.py
    import ConfigParser
    cf = ConfigParser.ConfigParser(allow_no_value=True)
    cf.read("./ini.ini")
    print(cf.sections())
    print(cf.options("test1"))
    print(cf.items("test1"))
    [root@localhost tmp]# python test.py
    ['test1', 'test2']
    ['key1', 'key2']
    [('key1', 'value'), ('key2', None)]

    17 楼方案的 py2.7 的实践结果,py3 里面的改名叫 configparser 了,换一下应该就可。
    yucongo
        26
    yucongo  
       2021-01-07 11:45:28 +08:00 via Android
    pydantic + dotenv
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   4909 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 36ms · UTC 01:09 · PVG 09:09 · LAX 17:09 · JFK 20:09
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.