pyparsing:如何获取令牌位置?

gri*_*yvp 3 python pyparsing

我有一个简单的pyparsing语法来匹配由空格分隔的数字:

from pyparsing import *
NUMBER = Word( nums )
STATEMENT = ZeroOrMore( NUMBER )
print( STATEMENT.parseString( "1 2 34" ) )
Run Code Online (Sandbox Code Playgroud)

给定1 2 34测试字符串,它返回 3 个已解析标记的字符串。但是如何在原始字符串中找到每个标记的位置?我需要它来进行“某种”语法高亮显示。

Pau*_*McG 5

将此解析操作添加到 NUMBER:

NUMBER.setParseAction(lambda locn,tokens: (locn,tokens[0]))
Run Code Online (Sandbox Code Playgroud)

解析操作可以传递为给定表达式解析的标记、解析的位置和原始字符串。您可以将函数传递给setParseAction使用以下任何签名:

fn()
fn(tokens)
fn(locn,tokens)
fn(srctring,locn,tokens)
Run Code Online (Sandbox Code Playgroud)

根据您的需要,您只需要位置和解析的令牌。

添加此解析操作后,您的解析结果现在如下所示:

[(0, '1'), (2, '2'), (4, '34')]
Run Code Online (Sandbox Code Playgroud)

编辑:

自从我对这篇文章的最初回答以来,我已经添加到 pyparsinglocatedExpr助手,它将给出特定表达式的开始和结束位置。现在这可以简单地写成:

NUMBER = locatedExpr(Word(nums))
Run Code Online (Sandbox Code Playgroud)

这是完整的脚本/输出:

>>> from pyparsing import *
... NUMBER = locatedExpr(Word( nums ))
... STATEMENT = ZeroOrMore( NUMBER )
... print( STATEMENT.parseString( "1 2 34" ).dump() )

[[0, '1', 1], [2, '2', 3], [4, '34', 6]]
[0]:
  [0, '1', 1]
  - locn_end: 1
  - locn_start: 0
  - value: '1'
[1]:
  [2, '2', 3]
  - locn_end: 3
  - locn_start: 2
  - value: '2'
[2]:
  [4, '34', 6]
  - locn_end: 6
  - locn_start: 4
  - value: '34'
Run Code Online (Sandbox Code Playgroud)