如何用pyparsing匹配到#{前文本并正确解析字符串模板
解决pyparsing解析#{...}模板字符串的问题
原代码的核心问题在于text_part = CharsNotIn('#{')的使用:CharsNotIn会匹配单个字符不在指定集合内的内容,所以遇到单独的#或{就会停止匹配,导致只能解析到第一个#之前的文本。
修正后的代码
from pyparsing import ( SkipTo, Suppress, Literal, Group, OneOrMore, stringEnd, Combine ) # 定义模板占位符:匹配#{...},提取中间内容 hash_tag = Group(Suppress(Literal('#{')) + SkipTo('}') + Suppress(Literal('}'))) # 定义普通文本部分:匹配到下一个占位符或字符串结尾的所有内容 text_part = Combine(SkipTo(hash_tag | stringEnd)) # 组合语法:交替匹配普通文本和占位符,至少匹配一次 parser = OneOrMore(text_part | hash_tag) test_string = "Some text \n with a stranded # and a stranded { then a correct #{ insertion of \n some # other text } and then some text" result = parser.parseString(test_string) # 转换为列表格式方便对比 result_list = [str(item) if not isinstance(item, list) else item.asList() for item in result] expected_result = [ "Some text \n with a stranded # and a stranded { then a correct ", [" insertion of \n some # other text "], " and then some text" ] print("解析结果:", result_list) print("是否符合预期:", result_list == expected_result)
关键改动说明
- 用
SkipTo(hash_tag | stringEnd)替代CharsNotIn('#{'):SkipTo会持续匹配直到遇到指定的终止符(这里是#{或字符串结束),支持包含单独#、{和换行符的文本。 - 用
Combine包裹SkipTo:确保普通文本部分被合并为单个字符串,避免拆分成多个字符元素。 - 调整语法顺序:
text_part | hash_tag保证先匹配普通文本到下一个占位符,再匹配占位符本身,循环完成整个字符串的解析。
运行后解析结果将完全符合预期。
内容的提问来源于stack exchange,提问作者Fogux
相关产品推荐
相关产品推荐

