2014-12-18 79 views
3

这里是我的代码:Pyparsing分隔的列表仅返回第一个元素

l = "1.3E-2 2.5E+1" 
parser = Word(alphanums + '+-.') 
grammar = delimitedList(parser,delim='\t ') 
print(grammar.parseString(l)) 

它返回:

['1.3E-2'] 

Obiously,我希望所有的这两个值,不是单一的一个,任何想法是怎么回事上 ?

回答

6

作品,如果你切换到原始字符串:

l = r"1.3E-2\t2.5E+1" 
parser = Word(alphanums + '+-.') 
grammar = delimitedList(parser, delim=r'\t') 
print(grammar.parseString(l)) 

打印:

['1.3E-2', '2.5E+1'] 

一般来说,delimitedList可与类似PDPDP其中P是解析目标和D是delimter或划界序列。

您有delim='\t '。具体而言,是1个选项卡后跟1个空格的分隔符;它不是标签或空间。

6

正如@dawg所解释的,delimitedList适用于您将表达式分隔为非空白分隔符(通常为逗号)的情况。 Pyparsing隐式跳过空白,所以在pyparsing世界中,你真正看到的不是一个分隔列表,而是OneOrMore(realnumber)。另外,除非使用parseWithTabs=True参数,否则parseString会在所提供的输入字符串内部调用str.expandtabs。将制表符扩展为空格有助于保持列表形式的数据的列对齐,并且当我最初编写pyparsing时,这是一个流行的用例。

如果您可以控制此数据,那么您可能希望使用与<TAB>不同的分隔符,可能是逗号或分号。如果您坚持使用此格式,但决定使用pyparsing,请使用OneOrMore。

随着您的前进,您还希望更精确地了解您定义的表达式和您使用的变量名称。 “解析器”这个名称并不是很丰富,Word(alphanums+'+-.')的模式在科学记数法中除了有效的实际值之外还会匹配很多事物。我知道如果你只是想任何东西工作,这是一个合理的第一次切割,你可以回来调整它,一旦你得到了什么。如果事实上你将要分析的实数,这里是一个可能有用的表达式:

realnum = Regex(r'[+-]?\d+\.\d*([eE][+-]?\d+)?').setParseAction(lambda t: float(t[0])) 

然后,你可以定义你的语法为“零或更多(realnum)”,这也是很多更多的自我解释。解析操作会将您的字符串转换为解析时的浮点数,这会在实际使用解析的值时为您节省一些时间。

祝你好运!

+0

感谢保罗对这个问题的答复,特别是详细的解释。我将移动到OneOrMore(它实际上是我尝试的第一件事,但这个原始字符串错误让我看起来像delimitedList)。我正在使用这个正则表达式,关于变量名称的同样的事情,为了简单起见,我只写了一个快速而肮脏的例子。 – Overdrivr

相关问题