【问题标题】:get the path in a file inside {} by python通过python获取{}内文件中的路径
【发布时间】:2014-09-04 21:51:18
【问题描述】:

我有一个代码,我只想返回 /X/Y/Z/C、/X/Y/Z/D、/X/Y/Z/E(无论 -tree 之后的内容)。 它实际上应该读取文件,忽略所有内容,直到它看到 WFS,然后在 {} 中获取信息,找到树并返回路径。

我是 Python 的初学者。匹配模式不起作用,因为我认为路径每天都在变化。 任何帮助将不胜感激。

代码:

DEFAULTS
{
    FS
    {
        -A      AAA
        -B

    }  -aaaaaa
    C
    {

    } 
}

D "FW0" 
{
} 

WFS "C:" XXXX:"/C"
{
    -trees
        "/X/Y/Z/C"
        "/X/Y/Z/D"
        "/X/Y/Z/E"
    -A  AAA
}

【问题讨论】:

  • 这个输入的预期输出是什么?
  • 输出应该返回“-trees”之后的路径。
  • 那么在您的情况下,引号中的三行?
  • 是的,但它总是会有所不同。一天可能是 1 行,第二天是 8 行。
  • 请问这个特殊格式是什么?你能找到你需要的解析器(例如 JSON)吗?

标签: python


【解决方案1】:

基于状态机的词法分析器可以可靠地完成这项工作。

它识别出我们感兴趣的文件结构:嵌套花括号、命名节(下一行的标识符和左大括号;这个只关心顶级节)和子句(以 -identifier 开头,在顶级节,可能跟随着数据行并由另一个子句或节的结尾终止)。

然后它继续读取文件并打印找到的数据行,如果它们恰好位于我们感兴趣的部分和子句中。它还会在找到它们时设置一个标志,以便在该子句结束后立即退出。

f = open("t.txt")

import re

identifier=None
brace_level=0
section=None
clause=None
req_clause_found=False
def in_req_clause(): return section=='WFS' and clause=='trees'

for l in (l.strip() for l in f):
    if req_clause_found and not in_req_clause(): break

    m=re.match(r'[A-Z]+',l)    #adjust if section names can be different
    if m and section is None:
        identifier=m.group(0)
        continue
    m=re.match(r'\{(\s|$)',l)
    if m:
        brace_level+=1
        if identifier is not None and brace_level==1:
            section=identifier
            identifier=None
        continue
    else: identifier=None
    m=re.match(r'\}(\s|$)',l)
    if m:
        brace_level-=1
        if brace_level==0: section=None
        clause=None
        continue
    m=re.match(r'-([A-Za-z]+)',l)   #adjust if clause names can be different
    if m and brace_level==1:
        clause=m.group(1)
        continue
    m=re.match(r'"(.*)"$',l)
    if m and in_req_clause():
        print m.group(1)
        req_clause_found=True
        continue

在示例中,此输出

/X/Y/Z/C
/X/Y/Z/D
/X/Y/Z/E

【讨论】:

  • 非常感谢。它适用于我在此处介绍的代码。我如何以及在哪里可以了解有关您使用的方法的更多信息?我的意思是使用标识符、子句……
  • 状态机的任何可理解的概述信息及其基本原理的词法分析。这里的状态是所有变量的组合。我不是先检查状态,然后检查输入(状态机的规范方法),而是先检查输入,然后检查状态(如果状态不相关,则隐式忽略输入)——这为此类任务产生的代码更少。 “标识符”、“节”和“子句”只是我发明的名称,用于指定我在此处识别的文件结构。
【解决方案2】:

我对您文件的布局有点困惑,但有什么理由不逐行解析它吗?

def parse():
    with open('data.txt') as fptr:
        for line in fptr:
            if line.startswith('WFS'):
                for line in fptr:
                    if line.strip().startswith('-trees'):
                        result = []
                        for line in fptr:
                            if line.strip().startswith('"'):
                                result.append(line.strip())
                            else:
                                return result

这不漂亮,但我认为它会工作!让我们试试吧:

In [1]: !cat temp.txt
DEFAULTS
{
    FS
    {
        -A      AAA
        -B

    }  -aaaaaa
    C
    {

    } 
}

D "FW0" 
{
} 

WFS "C:" XXXX:"/C"
{
    -trees
        "/X/Y/Z/C"
        "/X/Y/Z/D"
        "/X/Y/Z/E"
    -A  AAA
}

In [2]: %cpaste
Pasting code; enter '--' alone on the line to stop or use Ctrl-D.
:def parse():
:    with open('temp.txt') as fptr:
:        for line in fptr:
:            if line.startswith('WFS'):
:                for line in fptr:
:                    if line.strip().startswith('-trees'):
:                        result = []
:                        for line in fptr:
:                            if line.strip().startswith('"'):
:                                result.append(line.strip())
:                            else:
:                                return result
:
:--

In [3]: parse()
Out[3]: ['"/X/Y/Z/C"', '"/X/Y/Z/D"', '"/X/Y/Z/E"']

【讨论】:

  • 谢谢,但它没有返回任何东西!
  • 这忽略了花括号。
  • @BA 查看编辑。当我调用parse()时它返回['"/X/Y/Z/C"', '"/X/Y/Z/D"', '"/X/Y/Z/E"']
  • @AmyForbes。感谢您的代码,但它真的没有给我任何回报。我只有黑色终端没有结果。也许这是我的错,因为我是学习和运行编程的新手。当我插入 -- 最后,我得到 SyntaxError: invalid Syntax。我认为您正在使用 Canopy,我尝试安装它。
【解决方案3】:

我不确定你的模式的确切变化是什么,但你可以使用正则表达式组:

import re

myjunk = open("t.txt", "r")

for line in myjunk:
    if re.match('(/[A-Z])*', line)
        print line,

您可能需要稍微调整一下正则表达式,但这里的重点是花一点时间学习正则表达式,您不必处理其他地方建议的一些不必要的复杂解决方案。正则表达式是一种迷你语言,专为与文本相关的许多事情而构建,它确实是必不可少的知识,即使对于 python 新手也是如此。你会很高兴你投入时间! python 社区很有帮助,所以为什么不加入 IRC,我们会在你最喜欢的 python 频道中看到你的实时帮助。

祝你好运,如果您需要更多帮助,请告诉我。

PJ

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-10
    • 1970-01-01
    • 2011-12-29
    • 1970-01-01
    • 2021-05-05
    • 2017-04-14
    相关资源
    最近更新 更多