python - 用大括号解析文件

标签 python parsing pyparsing

我需要解析一个信息用大括号分隔的文件,例如:

Continent
{
Name    Europe
Country
{
Name    UK
Dog
{
Name    Fiffi
Colour  Gray
}
Dog
{
Name    Smut
Colour  Black
}
}
}

这是我在 Python 中尝试过的

from io import open
from pyparsing import *
import pprint

def parse(s):
    return nestedExpr('{','}').parseString(s).asList()

def test(strng):
    print strng
    try:
        cfgFile = file(strng)
        cfgData = "".join( cfgFile.readlines() )
        list = parse( cfgData )
        pp = pprint.PrettyPrinter(2)
        pp.pprint(list)

    except ParseException, err:
        print err.line
        print " "*(err.column-1) + "^"
        print err

    cfgFile.close()
    print
    return list

if __name__ == '__main__':
    test('testfile')

但这失败并出现错误:

testfile
Continent
^
Expected "{" (at char 0), (line:1, col:1)

Traceback (most recent call last):
  File "xxx.py", line 55, in <module>
    test('testfile')
  File "xxx.py", line 40, in test
    return list
UnboundLocalError: local variable 'list' referenced before assignment  

我需要做什么才能完成这项工作? 另一个解析器是否比 pyparsing 更好?

最佳答案

嵌套表达式很常见,如果您不使用解析库,通常需要递归解析器定义或递归代码。这段代码可能会让初学者望而生畏,甚至对于专家来说也容易出错,所以这就是我将 nestedExpr 帮助器添加到 pyparsing 的原因。

您遇到的问题是您的输入字符串中不仅仅是一个嵌套的大括号表达式。当我第一次尝试解析器时,我会尽量保持测试简单 - 例如,我内联示例而不是从文件中读取它。

test = """\
Continent
{
Name    Europe
Country
{
Name    UK
Dog
{
Name    Fiffi
Colour  "light Gray"
}
Dog
{
Name    Smut
Colour  Black
}}}"""

from pyparsing import *

expr = nestedExpr('{','}')

print expr.parseString(test).asList()

我得到了和你一样的解析错误:

Traceback (most recent call last):
  File "nb.py", line 25, in <module>
    print expr.parseString(test).asList()
  File "c:\python26\lib\site-packages\pyparsing-1.5.7-py2.6.egg\pyparsing.py", line 1006, in parseString
    raise exc
pyparsing.ParseException: Expected "{" (at char 1), (line:1, col:1)

因此查看错误消息(甚至查看您自己的调试代码),pyparsing 在前导词“Continent”上绊倒了,因为这个词不是括号中嵌套表达式的开头,pyparsing(正如我们在异常消息)正在寻找开头的“{”。

解决方案是稍微修改您的解析器以处理介绍性的“Continent”标签,方法是将 expr 更改为:

expr = Word(alphas) + nestedExpr('{','}')

现在,将结果打印为列表(使用 OP 中完成的 pprint,干得不错)如下所示:

['Continent',
 ['Name',
  'Europe',
  'Country',
  ['Name',
   'UK',
   'Dog',
   ['Name', 'Fiffi', 'Colour', '"light Gray"'],
   'Dog',
   ['Name', 'Smut', 'Colour', 'Black']]]]

这应该与您的大括号嵌套相匹配。

关于python - 用大括号解析文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16958087/

相关文章:

Python-删除 float 字符串

javascript - 在 IE 中加载和解析 XML

algorithm - 确定网站的 session 时间

python - pyparsing - 同一条语句的第二次执行抛出异常

python - pyparsing:从解析的数据中获取结果

Python 存储数据

python - 在 python 中从 (2,MN) 矩阵读取 (M,N) 图像的值

Python 可执行导入错误

c++ - C++中的前缀递归表示法

python - 在 pyparsing 中使用 QuotedString