Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/18.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解析器组合器_Python_Regex_Python 3.x_Parsing_Parser Combinators - Fatal编程技术网

用于捕获分隔符内文本的Python解析器组合器

用于捕获分隔符内文本的Python解析器组合器,python,regex,python-3.x,parsing,parser-combinators,Python,Regex,Python 3.x,Parsing,Parser Combinators,我正在查看Python中的一些解析器组合器库(更准确地说),我目前面临以下问题,下面的示例将其简化为一个简单的工作示例: text='' aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 被抓获停止中交 ''' 开

我正在查看Python中的一些解析器组合器库(更准确地说),我目前面临以下问题,下面的示例将其简化为一个简单的工作示例:

text=''
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
被抓获停止中交
'''
开始,停止=r“开始”,r“停止”
s=区段(文本、开始、停止)
印刷品
应输出:

 THE TEXT HERE SHOULD 
BE CAPTURED 
我目前正在研究的解决方案是通过执行一个regex前瞻,它工作得很好,但我最初的问题是将这些小regex组合在一起,这可能会变得很混乱,并且会给其他人带来以后维护的问题

从键入导入模式,TypeVar
进口稀土
#泛型类型声明。
T=类型变量(“T”)
def first(文本:str,模式:str,默认值:T,标志=0)->T:
"""
给定“text”、regex“pattern”和“default”值,返回第一个匹配项
在“text”中。否则,如果未找到匹配项,则返回“default”值。
"""
match=re.findall(模式、文本、标志=标志)
如果len(match)>0,则返回match[0],否则为默认值
定义部分(文本:str,开始:str,结束:str)->str:
"""
给定一个'text'和两个'start'和'stop'正则表达式,返回捕获的组
在间隔中找到。否则,如果未找到匹配项,则返回空字符串。
"""
首先返回(文本,fr“{begin}([\s\s]*?)(?={end})”,默认为“”
解析器组合器似乎非常适合此类情况,但我无法重现与工作解决方案相同的行为,欢迎提供任何提示:

# A Simpler example with hardcoded stuff
from parsy import regex, seq, string

text = '''
AAAAAAAAAA AAAAAAAA AAAAAAAAAAAAAA
BBBBBBB START THE TEXT HERE SHOULD
BE CAPTURED STOP CCCCCCCCCC CCCCCC
'''

start = regex(r"STARTS?")
middle = regex(r"[\s\S]*").optional()
stop = regex(r"STOPS?")

eol = string("\n")

# Work fine
start.parse("START")
middle.parse("")
stop.parse("STOP")

section = seq(
    start,
    middle,
    stop
)
# Simpler case, breaks
section.parse("START AAA STOP")

给出:

---------------------------------------------------------------------------
ParseError                                Traceback (most recent call last)
<ipython-input-260-fdec112e1648> in <module>
     24 )
     25 # Simpler case, breaks
---> 26 section.parse("START AAA STOP")

~/.venv/lib/python3.8/site-packages/parsy/__init__.py in parse(self, stream)
     88     def parse(self, stream):
     89         """Parse a string or list of tokens and return the result or raise a ParseError."""
---> 90         (result, _) = (self << eof).parse_partial(stream)
     91         return result
     92 

~/.venv/lib/python3.8/site-packages/parsy/__init__.py in parse_partial(self, stream)
    102             return (result.value, stream[result.index:])
    103         else:
--> 104             raise ParseError(result.expected, stream, result.furthest)
    105 
    106     def bind(self, bind_fn):

ParseError: expected 'STOPS?' at 0:14


---------------------------------------------------------------------------
ParseError回溯(上次最近的调用)
在里面
24 )
25#更简单的情况,中断
--->第26节解析(“开始AAA停止”)
解析中的~/.venv/lib/python3.8/site packages/parsy/_init__.py(self,stream)
88 def解析(自、流):
89“解析字符串或标记列表并返回结果或引发ParseError。”“”
--->90(结果,)=(自身错误(result.expected,stream,result.furthest)
105
106 def绑定(自,绑定):
ParseError:应在0:14“停止”

您是否尝试使用拆分

根据我对贵项目要求的理解,我将这样做:

text = '''
AAAAAAAAAA AAAAAAAA AAAAAAAAAAAAAA
BBBBBBB START THE TEXT HERE SHOULD
BE CAPTURED STOP CCCCCCCCCC CCCCCC
'''
# split text at START and take the second part of the text
# Then split the result by STOP and take the first part of the text
s = text.split('START')[1].split('STOP')[0]
print (s)

你试过使用split吗

根据我对贵项目要求的理解,我将这样做:

text = '''
AAAAAAAAAA AAAAAAAA AAAAAAAAAAAAAA
BBBBBBB START THE TEXT HERE SHOULD
BE CAPTURED STOP CCCCCCCCCC CCCCCC
'''
# split text at START and take the second part of the text
# Then split the result by STOP and take the first part of the text
s = text.split('START')[1].split('STOP')[0]
print (s)

问题是,
中间的
解析器匹配文本直到结束,因此,
停止
解析器不需要使用任何内容:

seq(开始,中间)。解析(“开始,停止”)
印刷品

['START', ' AAA STOP']
避免此行为的一个解决方案是对
middle
regex使用lookahead选项:

middle = regex(r"[\s\S]*(?=STOP)").optional()
这确保匹配的文本后面跟着“停止”字

或者,您可以使用Parsy的方法:

middle = (regex(r"STOPS?").should_fail("not STOP") >> any_char).many().concat()

问题是,
中间的
解析器匹配文本直到结束,因此,
停止
解析器不需要使用任何内容:

seq(开始,中间)。解析(“开始,停止”)
印刷品

['START', ' AAA STOP']
避免此行为的一个解决方案是对
middle
regex使用lookahead选项:

middle = regex(r"[\s\S]*(?=STOP)").optional()
这确保匹配的文本后面跟着“停止”字

或者,您可以使用Parsy的方法:

middle = (regex(r"STOPS?").should_fail("not STOP") >> any_char).many().concat()

不,split不能解决更复杂的模式,“开始”和“停止”只是一个简化的例子。问题是使用解析器组合器会是什么样子。不,split不能解决更复杂的模式,“开始”和“停止”这只是一个简化的例子。问题是关于使用解析器组合器会是什么样子?感谢您的回答@dan oneață!抱歉延迟接受感谢您的回答@dan oneață!抱歉延迟接受