Python 将Combine(文字(';@';)+;';spec';)更改为关键字(';@spec';)将删除空白
为什么使用Python 将Combine(文字(';@';)+;';spec';)更改为关键字(';@spec';)将删除空白,python,pyparsing,Python,Pyparsing,为什么使用Combine(…)保留空格,而关键字(…)删除空格 我需要保留匹配标记后的空格 测试如下: 从pyparsing导入* def解析(字符串,参照模式): 打印refpattern.searchString(字符串) pattern=StringStart()\ +SkipTo(参考模式)(“上一个”)\ +refpattern('ref')\ +SkipTo(StringEnd())(“rest”) 打印模式.parseString(字符串) string=“带@ref to_某物”
Combine(…)
保留空格,而关键字(…)
删除空格
我需要保留匹配标记后的空格
测试如下:
从pyparsing导入*
def解析(字符串,参照模式):
打印refpattern.searchString(字符串)
pattern=StringStart()\
+SkipTo(参考模式)(“上一个”)\
+refpattern('ref')\
+SkipTo(StringEnd())(“rest”)
打印模式.parseString(字符串)
string=“带@ref to_某物”
标识符=组合(单词(alphas+''''''''''''''''''''''''''''''''''')+可选('.''.+单词(alphas)))
不带空格的模式=(CaselessKeyword('@ref')| CaselessKeyword(r'\ref')).setParseAction(lambda s,l,t:['ref']))\
+白色().suppress()+标识符
模式_with_space=Combine((Literal('@'))| Literal('\\')).suppress()+'ref')+White().suppress()+标识符
解析(字符串、无空格的模式)
解析(字符串、带空格的模式)
将输出:
[['ref', 'to_something']]
['With', 'ref', 'to_something', '']
[['ref', 'to_something']]
['With ', 'ref', 'to_something', '']
# ^ space i need is preserved here
当对
caselesskyword
使用alternation(|
操作符)时,会出现问题。参见以下示例:
from pyparsing import *
theString = 'This is @Foo Bar'
identifier = Combine(Word(alphas + '_', alphanums + '_') + Optional('.' + Word(alphas)))
def testParser(p):
q = StringStart() + SkipTo(p)("previous") + p("body") + SkipTo(StringEnd())("rest")
return q.parseString(theString)
def test7():
p0 = (CaselessKeyword('@Foo') | Literal('@qwe')) + White().suppress() + identifier
p1 = (CaselessKeyword('@Foo') | CaselessKeyword('@qwe')) + White().suppress() + identifier
p2 = (Literal('@qwe') | CaselessKeyword('@Foo')) + White().suppress() + identifier
p3 = (CaselessKeyword('@Foo')) + White().suppress() + identifier
p4 = Combine((Literal('@') | Literal('\\')).suppress() + 'Foo') + White().suppress() + identifier
print "p0:", testParser(p0)
print "p1:", testParser(p1)
print "p2:", testParser(p2)
print "p3:", testParser(p3)
print "p4:", testParser(p4)
test7()
输出为:
p0: ['This is', '@Foo', 'Bar', '']
p1: ['This is', '@Foo', 'Bar', '']
p2: ['This is', '@Foo', 'Bar', '']
p3: ['This is ', '@Foo', 'Bar', '']
p4: ['This is ', 'Foo', 'Bar', '']
也许这是一个错误
更新:这是您如何定义自己的解析器以匹配关键字@Foo
或\Foo
:
from pyparsing import *
import string
class FooKeyWord(Token):
alphas = string.ascii_lowercase + string.ascii_uppercase
nums = "0123456789"
alphanums = alphas + nums
def __init__(self):
super(FooKeyWord,self).__init__()
self.identChars = alphanums+"_$"
self.name = "@Foo"
def parseImpl(self, instring, loc, doActions = True):
if (instring[loc] in ['@', '\\'] and
instring.startswith('Foo', loc+1) and
(loc+4 >= len(instring) or instring[loc+4] not in self.identChars) and
(loc == 0 or instring[loc-1].upper() not in self.identChars)):
return loc+4, instring[loc] + 'Foo'
raise ParseException(instring, loc, self.errmsg, self)
def test8():
p = FooKeyWord() + White().suppress() + identifier
q = StringStart() + SkipTo(p)("previous") + p("body") + SkipTo(StringEnd())("rest")
print "with @Foo:", q.parseString("This is @Foo Bar")
print "with \\Foo:", q.parseString("This is \\Foo Bar")
以及输出:
with @Foo: ['This is ', '@Foo', 'Bar', '']
with \Foo: ['This is ', '\\Foo', 'Bar', '']