全部
我找到了一段代码来解析简单的 ARFF 文件,我想更改它以适应稀疏 ARFF,其数据如下:
@data
{0 12,4 37,8 First,20 'Some Thing'}
{0 12,13 First,28 'Some Thing'}
这是代码:
def ParseFromSimpleARFF(data):
arffFormat = Forward()
E = CaselessLiteral("E")
comment = '%' + restOfLine
relationToken = Keyword('@RELATION', caseless=True)
dataToken = Keyword('@DATA', caseless=True)
attribToken = Keyword('@ATTRIBUTE', caseless=True)
ident = Word( alphas, alphanums + '_-' ).setName('identifier')
relation = Suppress(relationToken) \
+ ident.setResultsName('relation')
classDomain = Suppress('{') \
+ Group(delimitedList(ident.setResultsName('domain'))).setResultsName('domains') + Suppress('}')
attribute = Group(Suppress(attribToken)
+ Word(alphas).setResultsName('attrname')+(Word(alphas)|classDomain).setResultsName('type')).setResultsName('attribute')
arithSign = Word("+-",exact=1)
realNum = Combine( Optional(arithSign)
+ (Word( nums ) + "." + Optional( Word(nums) )|( "." + Word(nums) ))
+ Optional( E + Optional(arithSign) + Word(nums) ))
**#dataList = Group(delimitedList(realNum|ident)).setResultsName('record')
dataList = Suppress('{') + Group( delimitedList(realNum|ident)).setResultsName('record') + Suppress('}')**
arffFormat << ( relation
+ OneOrMore(attribute).setResultsName('attributes')
+ dataToken
+ OneOrMore(dataList).setResultsName('records')).setResultsName('arffdata')
simpleARFF = arffFormat
simpleARFF.ignore(comment)
tokens = simpleARFF.parseString(data)
return tokens
但是不起作用
我想我必须告诉程序识别空白,但我不知道如何
非常感谢
最佳答案
不不不! pyparsing 的一个重要部分是“出现空格”!除非您正在使用基于缩进的解析或面向行的数据做一些棘手的事情,否则请将空格保留在解析器定义之外。
您的问题是您定义的 dataList 与您提供的列表不匹配。列表中的每个逗号分隔项都是一对值,这似乎允许数字或带引号的字符串。因此将 dataList 定义为:
dataCell = realNum|ident|quotedString
dataList = Suppress('{') + Group( delimitedList(Group(dataCell + dataCell))) + Suppress('}')
其他一些位:
没有必要将 arffFormat 声明为 Forward()。仅当数据嵌套在递归结构(即包含子数据的数据)中时才需要这样做。您的示例没有,只需在末尾定义 arffFormat
arffFormat = (...etc.
x.setResultsName('name')
已简单地替换为x('name')
,真正清理了解析器代码您定义了一个 realNum(需要小数点),但样本中只有整数。我已经不再构建 realNum 类型表达式,而是使用本地化的正则表达式:
realNum = Regex(r"[+-]?\d+(\.\d*)?([Ee][+-]?\d+)?")
会给你一个接受整数或实数的表达式。这还允许您删除其他分散注意力的元素,例如 arithSign。
您可能对结果名称也太过分了。我认为这将使您对数据有一个很好的了解,并在最后给出一个非常易于导航的结构:
arffFormat = ( relation
+ OneOrMore(attribute)('attributes')
+ dataToken
+ OneOrMore(dataList)('records'))('arffdata')
关于python - 使用 pyparsing 解析稀疏 ARFF 时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6266743/