我尝试使用pyparsing来解析robotframework,这是一个基于文本的DSL。sytnax如下(抱歉,但我觉得用BNF来描述它有点困难)。 robotframework中的一行代码可能看起来像:
Library\tSSHClient with name\tnode
\t是tab,在robotframework中,它被透明地传输到2“”(实际上,它只是调用结构更换('\t','')替换制表符,但它将修改每行的实际长度,len('\t')为1,而len('')为2.)。 在robot中,使用2个或更多的空白和'\t'来分割标记,如果单词之间只有1个空格,则将单词视为一个标记组。在
Library\tSSHClient with name\tnode
如果解析正确,则实际拆分为以下标记:
['Library', 'SSHClient', 'with name', 'node']
由于“with”和“name”之间只有1个空格,所以解析器认为它属于一个组语法标记。在
这是我的代码:
ParserElement.setDefaultWhitespaceChars('\r\n\t ')
source = "Library\tSSHClient with name\tnode"
EACH_LINE = Optional(Word(" ")).leaveWhitespace().suppress() + \
CaselessKeyword("library").suppress() + \
OneOrMore((Word(alphas)) + White(max=1).setResultName('myValue')) +\
SkipTo(LineEnd())
res = EACH_LINE.parseString(source)
print res.myValue
问题:
1)我已经设置了空白,如果我想精确匹配2个或多个空白或一个或多个制表符,我想代码应该是: 白色(ws='',min=2)|白色(ws='\t',min=1) 但这将失败,所以我不能指定空白值?在
2)有没有办法得到匹配的结果指标?我尝试了setParseAction,但似乎无法通过此回调获取索引。我需要开始和结束索引来突出这个词。在
3)LineStart和LineEnd是什么意思?我打印这些值,看起来它们只是普通的字符串,我需要在一行前面写一些东西,比如: LineStart()+巴拉巴拉巴拉。。。+LineEnd()?在
谢谢,但是有一个限制,我无法将“\t”替换为“
from pyparsing import *
source = "Library\tsshclient\t\t\twith name s1"
value = Combine(OneOrMore(Word(printables) | White(' ', max=1) + ~White())) #here it seems the whitespace has already been set to ' ', why the result still match '\t'?
linedefn = OneOrMore(value)
res = linedefn.parseString(source)
print res
我得到了
['Library sshclient', 'with name', 's1']
但我预料到了 ['Library','sshclient','with name','s1']
当空格潜入已解析的标记中时,我总是畏缩,但是由于您的限制,只允许单个空格,这应该是可行的。我使用以下表达式定义可以嵌入单个空格的值:
完成此操作后,一行就是这些值中的一个或多个:
^{pr2}$以你为榜样,包括打电话结构更换要用空格对替换制表符,代码如下所示:
给予:
要获取原始字符串中任何值的起始位置和结束位置,请将表达式包装在新的pyparsing helper方法
locatedExpr
:如果我们分析并转储结果:
我们得到:
LineStart和LineEnd是pyparsing表达式类,它们的实例应该在行的开头和结尾处匹配。LineStart一直很难使用,但是LineEnd是可以预测的。在您的例子中,如果您一次只读取和解析一行,那么您不需要它们-只需定义您期望的行的内容。如果您想确保解析器已经处理了整个字符串(并且不会因为不匹配的字符而在结尾处停止),请将}添加到解析器的末尾,或者将参数
+ LineEnd()
或{parseAll=True
添加到对parseString()
的调用中。在编辑:
很容易忘记pyparsing调用str.expandtabs结构默认情况下-必须通过调用parseWithTabs禁用此功能。这样,以及显式地不允许在值词之间使用制表符可以解决问题,并使值保持正确的字符数。参见以下更改:
相关问题 更多 >
编程相关推荐