pyparsing使用nestedExpr解析嵌套列类型遇双闭合符报错如何解决
嵌套列类型解析连续>>报错的无预处理解决方案
问题根因
默认nestedExpr会以空格作为分词边界,无空格的连续闭合尖括号>>会被识别为单个token,无法匹配到对应的单个闭合符>,导致第5种场景解析失败。
无预处理实现方案
无需对输入字符串做替换预处理,通过显式指定各嵌套类型的开闭符号、自定义内容匹配规则即可解决,实现代码如下:
import pyparsing as pp # 基础元素定义 scalar_type = pp.Word(pp.alphas) # 匹配string/int/boolean等标量类型 col_name = pp.Word(pp.alphanums + '_') col_type_delimiter = pp.oneOf(': ') col_type = pp.Forward() # 列定义:列名 + 分隔符 + 类型 column = pp.Group(col_name('name') + col_type_delimiter + col_type('type')) col_list = pp.delimitedList(column) # 各嵌套类型单独定义精准开闭符 struct_type = pp.nestedExpr( opener=pp.Keyword("struct") + "<", closer=">", content=col_list | col_type, ignoreExpr=None )('struct') array_type = pp.nestedExpr( opener=pp.Keyword("array") + "<", closer=">", content=col_type | pp.delimitedList(col_type), ignoreExpr=None )('array') row_type = pp.nestedExpr( opener=pp.Keyword("row") + "(", closer=")", content=col_list | col_type, ignoreExpr=None )('row') # 递归赋值类型规则 col_type <<= (struct_type | array_type | row_type | scalar_type('scalar')) # 测试所有样例 test_cases = [ "string", "struct<col_1:string,col_2:int>", "row(col_1 string,array(col_2 string),col_3 boolean)", "array<struct<col_1:string,col_2:int>,col_3:boolean>", "array<struct<col_1:string,col2:int>>" ] for idx, case in enumerate(test_cases, 1): try: result = col_type.parseString(case, parseAll=True) print(f"用例{idx}解析成功") except Exception as e: print(f"用例{idx}解析失败: {e}")
核心改动说明
- 移除了通用的模糊开闭符号匹配规则,为struct、array、row类型分别指定精准的开闭符,避免跨类型符号识别错误
- 显式声明
nestedExpr的content可匹配元素,不依赖默认的空白分词逻辑 - 闭合符匹配改为逐字符扫描,可正确识别连续
>>中的两个独立闭合符,分别对应内层和外层嵌套结构的闭合
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

