Python 将纯文本与pyparsing匹配

Python 将纯文本与pyparsing匹配,python,pyparsing,Python,Pyparsing,我不知道如何按原样解析纯文本(也包括空格),并且仍然能够匹配文本中的特殊结构。假设你有一根像 some plain text specialStructure plain text again 我试图实现的是一个解析器,它为我 我的第一次尝试是 即使这给了我在这种情况下想要的东西,这里的问题是,如果纯文本有一些换行符、制表符或其他类型的空格,最后我只得到空格键分隔的单词 在找到特殊结构或输入端之前,如何匹配纯文本 更新 我发现的部分解决方案是使用SkipTo类: 这里的问题是嵌套结构。假

我不知道如何按原样解析纯文本(也包括空格),并且仍然能够匹配文本中的特殊结构。假设你有一根像

some plain text
specialStructure
plain text again
我试图实现的是一个解析器,它为我

我的第一次尝试是

即使这给了我在这种情况下想要的东西,这里的问题是,如果纯文本有一些换行符、制表符或其他类型的空格,最后我只得到空格键分隔的单词

在找到特殊结构或输入端之前,如何匹配纯文本

更新

我发现的部分解决方案是使用SkipTo类:

这里的问题是嵌套结构。假设您要解析一个更复杂的字符串,如:

s = """
some plain text
nestedStructureBegin
   here we are inside a nested structure
   nestedStructureBegin
      bla bla
   nestedStructureEnd
nestedStructureEnd
some bla bla again.
"""

import pyparsing as pp

grammar = pp.Forward()
begin = pp.Regex(r'nestedStructureBegin').suppress()
end = pp.Regex(r'nestedStructureEnd').suppress()
struct = begin + pp.Group(grammar) + end
keyword = begin | end
txt = pp.SkipTo( keyword ) | pp.SkipTo( pp.StringEnd(), include=True )
grammar << pp.ZeroOrMore( struct | txt )

for parser in [struct, txt]:
    parser.addParseAction(lambda toks: print(toks))

result = grammar.parseString(s)
s=”“”
一些纯文本
嵌套结构开始
这里我们在一个嵌套结构中
嵌套结构开始
布拉布拉
嵌套结构端
嵌套结构端
又是什么废话。
"""
将pyparsing导入为pp
语法=pp.Forward()
begin=pp.Regex(r'nestedStructureBeagin').suppress()
end=pp.Regex(r'nestedStructureEnd').suppress()
struct=begin+pp.Group(语法)+end
关键字=开始|结束
txt=pp.SkipTo(关键字)| pp.SkipTo(pp.StringEnd(),include=True)

语法我已经找到了一种即使在嵌套结构中也能很好地工作的解决方案。其思想是逐个字符解析输入字符,然后使用
pp.Combine
重构原始纯文本输入。

s=”“”
一些纯文本
开始
我们在一个嵌套的结构中
开始
再深一点
结束
结束
最后还有更多的废话。。。
"""
将pyparsing导入为pp
语法=pp.Forward()
begin=pp.Regex(r'begin').suppress()
end=pp.Regex(r'end').suppress()
关键字=开始|结束
block=begin+pp.Group(语法)+end
char=~关键字+pp.Regex(r'[\s\s]')
chars=pp.OneOrMore(char)
txt=pp.Combine(字符)

语法我还是不明白你的要求。你想得到一个具体内容的列表吗?我想要一个pyparsing.ParseResults对象,它提供了你调用asList()方法时我写的列表。请研究使用
scanString
searchString
,这将允许你只解析你的特殊结构并跳过其余部分。使用
scanString
,您还将获得解析的开始和结束位置,因此您可以使用字符串切片来提取解析前后的部分。@PaulMcG我已经更新了问题。我不想使用scanString,因为要匹配的结构可以是嵌套结构,正如我在更新中所解释的……如果使用
skipot
,请确保包含
failOn
属性(类似
failOn=end
),这样您就不会意外地将
SkipTo
覆盖到自己的终止端标记上。
import pyparsing as pp

def join_words(toks):
    return ' '.join(toks)

struct = pp.Regex(r'specialStructure')
word = ~struct + pp.Word(pp.alphas)
txt = pp.OneOrMore(word).addParseAction(join_words)
grammar = pp.ZeroOrMore(struct | txt)

result = grammar.parseString(s)
import pyparsing as pp

struct = pp.Regex(r'specialStructure')
txt = pp.SkipTo( struct ) | pp.SkipTo( pp.StringEnd(), include=True )
grammar = pp.ZeroOrMore( struct | txt )

result = grammar.parseString(s)
s = """
some plain text
nestedStructureBegin
   here we are inside a nested structure
   nestedStructureBegin
      bla bla
   nestedStructureEnd
nestedStructureEnd
some bla bla again.
"""

import pyparsing as pp

grammar = pp.Forward()
begin = pp.Regex(r'nestedStructureBegin').suppress()
end = pp.Regex(r'nestedStructureEnd').suppress()
struct = begin + pp.Group(grammar) + end
keyword = begin | end
txt = pp.SkipTo( keyword ) | pp.SkipTo( pp.StringEnd(), include=True )
grammar << pp.ZeroOrMore( struct | txt )

for parser in [struct, txt]:
    parser.addParseAction(lambda toks: print(toks))

result = grammar.parseString(s)
s = """
some plain text
begin
   we are inside a nested structure
   begin
      some more depth
   end
end
and finally some more bla bla...
"""

import pyparsing as pp

grammar = pp.Forward()
begin = pp.Regex(r'begin').suppress()
end = pp.Regex(r'end').suppress()
keyword = begin | end
block = begin + pp.Group(grammar) + end
char = ~keyword + pp.Regex(r'[\s\S]')
chars = pp.OneOrMore(char)
txt = pp.Combine(chars)
grammar << pp.ZeroOrMore( block | txt )

result = grammar.parseString(s)