如何对待前缀关键字?
How to treat prefixed keywords?
我有以下解析问题。我的关键字可以用下划线作为前缀,用于停用选项、块等。
#coding: utf8
from pyparsing import Keyword, Combine, pyparsing_common, Literal, Suppress, Group, OneOrMore
test_string = r'''
keyword1list {
keyword1 {
option 213
}
_keyword1 {
option 214
}
}
'''
任何关键字都可能发生这种情况,此处为 keyword1list
、keyword1
或 option
。我想要实现的是要么在解析过程中将这些块留在外面,要么解析它们但捕获停用前缀。
目前,我可以使用以下代码成功解析 "activated" test_string
,但由于带下划线的关键字的明显原因,它失败了。
lparent = Suppress(Literal('{'))
rparent = Suppress(Literal('}'))
kw1_block = Keyword('keyword1') + lparent
kw1_block = kw1_block + Keyword('option') + pyparsing_common.number.setResultsName('option')
kw1_block = Group(kw1_block + rparent).setResultsName('keyw1')
kw2_block = Keyword('keyword1list') + lparent
kw2_block = kw2_block+ OneOrMore(kw1_block) + rparent
kw2_block = Group(kw2_block).setResultsName('keyword1list', listAllMatches=True)
result = kw2_block.parseString(test_string)
print(result.dump())
tmp = kw2_block.runTests(test_string.replace('\n', '\n'))
print tmp[0]
我目前的解决方案是,把所有的关键字都放在一个列表中,然后建立一个字典,将它们与下划线结合起来,并给它们一个标志。
#coding: utf8
from pyparsing import Keyword, Combine, pyparsing_common, Literal, Suppress, Group, OneOrMore, ZeroOrMore
test_string = r'''
keyword1list {
_keyword1 {
option 1
}
keyword1 {
option 2
}
_keyword1 {
option 3
}
keyword1 {
option 4
}
keyword1 {
option 5
}
}
'''
kwlist = ['keyword1', 'keyword1list', 'option']
keywords = {}
for k in kwlist:
keywords[k] = Keyword('_' + k).setResultsName('deactivated') | Keyword(
k).setResultsName('activated')
lparent = Suppress(Literal('{'))
rparent = Suppress(Literal('}'))
kw1_block = keywords['keyword1'] + lparent
kw1_block = kw1_block + keywords[
'option'] + pyparsing_common.number.setResultsName('option') + rparent
kw1_block = Group(kw1_block).setResultsName('keyword1', listAllMatches=True)
kw2_block = keywords['keyword1list'] + lparent
kw2_block = kw2_block + ZeroOrMore(kw1_block) + rparent
kw2_block = Group(kw2_block).setResultsName('keyword1list')
result = kw2_block.parseString(test_string)
print(result.dump())
tmp = kw2_block.runTests(test_string.replace('\n', '\n'))
print tmp[0]
虽然这允许正确解析所有内容,但我必须在之后重新创建逻辑(找到停用的关键字并将它们从结果中删除),我想避免这种情况。我相信我需要在带下划线的关键字上添加 parseAction
才能以某种方式删除这些标记,但我目前不知道该怎么做。
非常感谢任何帮助。
当我看到一个旨在过滤掉选定文本块的解析器时,我的第一种方法通常是编写一个仅匹配选定部分的解析器,然后将 transformString 与该解析器的抑制形式一起使用:
kwlist = ['keyword1', 'keyword1list', 'option']
to_suppress = MatchFirst(Keyword('_' + k) for k in kwlist)
kw_body = nestedExpr("{", "}") | Word(nums)
filter = (to_suppress + kw_body).suppress()
print(filter.transformString(test_string))
运行 这与您的测试字符串给出:
keyword1list {
keyword1 {
option 2
}
keyword1 {
option 4
}
keyword1 {
option 5
}
}
我有以下解析问题。我的关键字可以用下划线作为前缀,用于停用选项、块等。
#coding: utf8
from pyparsing import Keyword, Combine, pyparsing_common, Literal, Suppress, Group, OneOrMore
test_string = r'''
keyword1list {
keyword1 {
option 213
}
_keyword1 {
option 214
}
}
'''
任何关键字都可能发生这种情况,此处为 keyword1list
、keyword1
或 option
。我想要实现的是要么在解析过程中将这些块留在外面,要么解析它们但捕获停用前缀。
目前,我可以使用以下代码成功解析 "activated" test_string
,但由于带下划线的关键字的明显原因,它失败了。
lparent = Suppress(Literal('{'))
rparent = Suppress(Literal('}'))
kw1_block = Keyword('keyword1') + lparent
kw1_block = kw1_block + Keyword('option') + pyparsing_common.number.setResultsName('option')
kw1_block = Group(kw1_block + rparent).setResultsName('keyw1')
kw2_block = Keyword('keyword1list') + lparent
kw2_block = kw2_block+ OneOrMore(kw1_block) + rparent
kw2_block = Group(kw2_block).setResultsName('keyword1list', listAllMatches=True)
result = kw2_block.parseString(test_string)
print(result.dump())
tmp = kw2_block.runTests(test_string.replace('\n', '\n'))
print tmp[0]
我目前的解决方案是,把所有的关键字都放在一个列表中,然后建立一个字典,将它们与下划线结合起来,并给它们一个标志。
#coding: utf8
from pyparsing import Keyword, Combine, pyparsing_common, Literal, Suppress, Group, OneOrMore, ZeroOrMore
test_string = r'''
keyword1list {
_keyword1 {
option 1
}
keyword1 {
option 2
}
_keyword1 {
option 3
}
keyword1 {
option 4
}
keyword1 {
option 5
}
}
'''
kwlist = ['keyword1', 'keyword1list', 'option']
keywords = {}
for k in kwlist:
keywords[k] = Keyword('_' + k).setResultsName('deactivated') | Keyword(
k).setResultsName('activated')
lparent = Suppress(Literal('{'))
rparent = Suppress(Literal('}'))
kw1_block = keywords['keyword1'] + lparent
kw1_block = kw1_block + keywords[
'option'] + pyparsing_common.number.setResultsName('option') + rparent
kw1_block = Group(kw1_block).setResultsName('keyword1', listAllMatches=True)
kw2_block = keywords['keyword1list'] + lparent
kw2_block = kw2_block + ZeroOrMore(kw1_block) + rparent
kw2_block = Group(kw2_block).setResultsName('keyword1list')
result = kw2_block.parseString(test_string)
print(result.dump())
tmp = kw2_block.runTests(test_string.replace('\n', '\n'))
print tmp[0]
虽然这允许正确解析所有内容,但我必须在之后重新创建逻辑(找到停用的关键字并将它们从结果中删除),我想避免这种情况。我相信我需要在带下划线的关键字上添加 parseAction
才能以某种方式删除这些标记,但我目前不知道该怎么做。
非常感谢任何帮助。
当我看到一个旨在过滤掉选定文本块的解析器时,我的第一种方法通常是编写一个仅匹配选定部分的解析器,然后将 transformString 与该解析器的抑制形式一起使用:
kwlist = ['keyword1', 'keyword1list', 'option']
to_suppress = MatchFirst(Keyword('_' + k) for k in kwlist)
kw_body = nestedExpr("{", "}") | Word(nums)
filter = (to_suppress + kw_body).suppress()
print(filter.transformString(test_string))
运行 这与您的测试字符串给出:
keyword1list {
keyword1 {
option 2
}
keyword1 {
option 4
}
keyword1 {
option 5
}
}