Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/meteor/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何使用pyparsing获取匹配令牌的位置?_Python_Pyparsing - Fatal编程技术网

Python 如何使用pyparsing获取匹配令牌的位置?

Python 如何使用pyparsing获取匹配令牌的位置?,python,pyparsing,Python,Pyparsing,到目前为止,我已经尝试使用“setParseAction”来获取匹配令牌的位置,但它有时并不像我预期的那样有效。以该代码为例: >>> from pyparsing import * >>> >>> Z = Literal('0') >>> POINT = Literal('.') >>> BIN_DIGITS = Word('01') >>> OCT_DIGITS = Word('01

到目前为止,我已经尝试使用“setParseAction”来获取匹配令牌的位置,但它有时并不像我预期的那样有效。以该代码为例:

>>> from pyparsing import *
>>> 
>>> Z = Literal('0')
>>> POINT = Literal('.')
>>> BIN_DIGITS = Word('01')
>>> OCT_DIGITS = Word('01234567')
>>> DEC_DIGITS = Word('0123456789')
>>> HEX_DIGITS = Word('0123456789abcdefABCDEF')
>>> DEC_INT = DEC_DIGITS.setParseAction(lambda t: int(t[0]))
>>> BIN_INT = Combine(Z + ((Literal('b') | 'B')) + BIN_DIGITS).\
...         setParseAction(lambda t: int(t[0], 2))
>>> OCT_INT = Combine(Z + ((Literal('o') | 'O')) + OCT_DIGITS).\
...         setParseAction(lambda t: int(t[0], 8))
>>> HEX_INT = Combine(Z + ((Literal('x') | 'X')) + HEX_DIGITS).\
...         setParseAction(lambda t: int(t[0], 16))
>>> INTEGER = HEX_INT | OCT_INT | BIN_INT | DEC_INT
>>> EXP = Combine(CaselessLiteral('E') + Optional(Literal('+') | '-') + DEC_INT)
>>> POINT_FLOAT = Combine(Optional(DEC_INT) + POINT + DEC_INT) | \
...         Combine(DEC_INT + POINT)
>>> EXP_FLOAT = Combine(DEC_INT + EXP) | Combine(POINT_FLOAT + EXP)
>>> FLOAT = (EXP_FLOAT | POINT_FLOAT).setParseAction(lambda t: float(t[0]))
>>> 
>>> 
>>> def p(s, l, t):
...     print 'Location of %s:  %s' % (t[0], l,)
... 
>>> 
>>> NUMBER = (FLOAT | INTEGER).setParseAction(p)
>>> NUMBER.parseString('    12345')
Location of 12345:  0
([12345], {})
>>> NUMBER.parseString(' 12345')
Location of 12345:  0
([12345], {})
>>> NUMBER.parseString('12345')
Location of 12345:  0
([12345], {})
位置始终为0,无论我将数字“12345”放置在字符串中的何处。但是,如果我尝试:

>>> LITERAL = Literal('someword').setParseAction(p)
>>> LITERAL.parseString('    someword')
Location of someword:  4
(['someword'], {})
>>> LITERAL.parseString(' someword')
Location of someword:  1
(['someword'], {})
>>> LITERAL.parseString('someword')
Location of someword:  0
(['someword'], {})

它按预期工作。在第一个示例中,我做错了什么?

好的,多亏了Paul的提示,我成功地解决了这个问题,将'Or'表达式与一个加压式空白表达式结合起来,并使用它来解析字符串。最终结果如下:

>>> from pyparsing import *
>>> 
>>> def p(s,l,t):
...     print 'Location of %s: %s' % (s, l,)
... 
>>> Z = Literal('0')
>>> POINT = Literal('.')
>>> BIN_DIGITS = Word('01')
>>> OCT_DIGITS = Word('01234567')
>>> DEC_DIGITS = Word('0123456789')
>>> HEX_DIGITS = Word('0123456789abcdefABCDEF')
>>> DEC_INT = DEC_DIGITS.copy().setParseAction(lambda t: int(t[0]))
>>> BIN_INT = Combine(Z + ((Literal('b') | 'B')) + BIN_DIGITS).\
...         setParseAction(lambda t: int(t[0], 2))
>>> OCT_INT = Combine(Z + ((Literal('o') | 'O')) + OCT_DIGITS).\
...         setParseAction(lambda t: int(t[0], 8))
>>> HEX_INT = Combine(Z + ((Literal('x') | 'X')) + HEX_DIGITS).\
...         setParseAction(lambda t: int(t[0], 16))
>>> INTEGER = HEX_INT | OCT_INT | BIN_INT | DEC_INT
>>> EXP = Combine(CaselessLiteral('E') + Optional(Literal('+') | Literal('-')) + DEC_DIGITS)
>>> POINT_FLOAT = Combine(Optional(DEC_DIGITS) + POINT + DEC_DIGITS) | \
...         Combine(DEC_DIGITS + POINT)
>>> EXP_FLOAT = Combine(DEC_DIGITS + EXP) | Combine(POINT_FLOAT + EXP)
>>> FLOAT = (EXP_FLOAT | POINT_FLOAT).setParseAction(lambda t: float(t[0]))
>>> NUMBER = (FLOAT | INTEGER).setParseAction(p)
>>> NUMBER2 = Combine(ZeroOrMore(White(exact=1)).suppress() + NUMBER)
>>> 
>>> NUMBER2.parseString('    12345')
Location of     12345: 4
(['12345'], {})

好的,多亏了Paul的提示,我成功地解决了这个问题,将'Or'表达式与一个加压式的空格表达式相结合,并使用它来解析字符串。最终结果如下:

>>> from pyparsing import *
>>> 
>>> def p(s,l,t):
...     print 'Location of %s: %s' % (s, l,)
... 
>>> Z = Literal('0')
>>> POINT = Literal('.')
>>> BIN_DIGITS = Word('01')
>>> OCT_DIGITS = Word('01234567')
>>> DEC_DIGITS = Word('0123456789')
>>> HEX_DIGITS = Word('0123456789abcdefABCDEF')
>>> DEC_INT = DEC_DIGITS.copy().setParseAction(lambda t: int(t[0]))
>>> BIN_INT = Combine(Z + ((Literal('b') | 'B')) + BIN_DIGITS).\
...         setParseAction(lambda t: int(t[0], 2))
>>> OCT_INT = Combine(Z + ((Literal('o') | 'O')) + OCT_DIGITS).\
...         setParseAction(lambda t: int(t[0], 8))
>>> HEX_INT = Combine(Z + ((Literal('x') | 'X')) + HEX_DIGITS).\
...         setParseAction(lambda t: int(t[0], 16))
>>> INTEGER = HEX_INT | OCT_INT | BIN_INT | DEC_INT
>>> EXP = Combine(CaselessLiteral('E') + Optional(Literal('+') | Literal('-')) + DEC_DIGITS)
>>> POINT_FLOAT = Combine(Optional(DEC_DIGITS) + POINT + DEC_DIGITS) | \
...         Combine(DEC_DIGITS + POINT)
>>> EXP_FLOAT = Combine(DEC_DIGITS + EXP) | Combine(POINT_FLOAT + EXP)
>>> FLOAT = (EXP_FLOAT | POINT_FLOAT).setParseAction(lambda t: float(t[0]))
>>> NUMBER = (FLOAT | INTEGER).setParseAction(p)
>>> NUMBER2 = Combine(ZeroOrMore(White(exact=1)).suppress() + NUMBER)
>>> 
>>> NUMBER2.parseString('    12345')
Location of     12345: 4
(['12345'], {})

如果执行INTEGER.addParseActionp.parseString“12345”,会发生什么情况?我认为您遇到了pyparsing中出现的默认空白跳过。根据语法中附加的解析操作的级别,位置可能在跳过前导空格之前或之后。你为什么要捕获这个位置?如果要使用按位置的字符串切片替换文本字段,请查看transformString是否是更好的API方法。我正在使用类似python的SyntaxIndended语法实现一种语言,我希望它的多行字符串文字的行为与这里描述的一样。为此,我使用了一个解析操作,该操作将多行字符串拆分成几行,并且对于每一行,在将行重新连接之前,删除字符串文本开始的列的前导空格。为此,我需要有匹配令牌的位置,以便调用“col”函数。您可以链接到此转换示例吗?显然,只有当要匹配的标记是输入流中的第一个时才会发生这种情况是的,因为匹配A | B | C实际上是匹配Or[A,B,C],而Or将在匹配A或B或C之前跳过前导空格。如果执行INTEGER.addParseActionp.parseString“12345”,会发生什么情况?我认为您遇到了pyparsing中出现的默认空白跳过。根据语法中附加的解析操作的级别,位置可能在跳过前导空格之前或之后。你为什么要捕获这个位置?如果要使用按位置的字符串切片替换文本字段,请查看transformString是否是更好的API方法。我正在使用类似python的SyntaxIndended语法实现一种语言,我希望它的多行字符串文字的行为与这里描述的一样。为此,我使用了一个解析操作,该操作将多行字符串拆分成几行,并且对于每一行,在将行重新连接之前,删除字符串文本开始的列的前导空格。为此,我需要有匹配令牌的位置,以便调用“col”函数。你能链接到这个转换示例吗?显然,只有当要匹配的标记是输入流中的第一个时才会发生这种情况是的,因为匹配A | B | C实际上是匹配Or[A,B,C],而Or将在匹配A或B或C之前跳过前导空格。