使用pyparsing set_parse_action()去除字符串空白遇错误及文本丢失问题
问题分析与解决方案
错误原因
- 原代码报错:
pp.token_map(str.strip)作用于Group返回的ParseResults对象,但str.strip仅能处理字符串,无法直接作用于ParseResults,因此触发类型错误。 - 自定义函数丢失文本:你使用了
token.str.strip(),但tokens中的元素是SkipTo返回的ParseResults对象,并没有str属性,导致实际未提取到文本内容。
解决方案
方案一:保留每行结构,单独去除每行空白
import pyparsing as pp def _strip_whitespace(tokens): # tokens[0] 是 OneOrMore 匹配到的所有行,每行是 SkipTo 返回的 ParseResults return [line[0].strip() for line in tokens[0]] text_block = pp.Group( pp.OneOrMore( pp.SkipTo(pp.LineEnd()) + pp.LineEnd().suppress(), stopOn=pp.StringEnd() | (pp.LineStart() + (pp.Literal("E)") | pp.Literal("F)"))) ) ).set_parse_action(_strip_whitespace)
方案二:在匹配每行时直接处理空白(更高效)
import pyparsing as pp # 对每行单独执行strip,再抑制换行符 line = pp.SkipTo(pp.LineEnd()).set_parse_action(lambda t: t[0].strip()) + pp.LineEnd().suppress() text_block = pp.Group( pp.OneOrMore( line, stopOn=pp.StringEnd() | (pp.LineStart() + (pp.Literal("E)") | pp.Literal("F)"))) ) )
方案三:将整个文本块合并为单个strip后的字符串
如果不需要保留每行结构,而是要整块文本的去空白结果:
import pyparsing as pp def _strip_block(tokens): # 拼接所有行,再整体去除首尾空白 full_text = '\n'.join(str(line[0]) for line in tokens[0]) return full_text.strip() text_block = pp.Group( pp.OneOrMore( pp.SkipTo(pp.LineEnd()) + pp.LineEnd().suppress(), stopOn=pp.StringEnd() | (pp.LineStart() + (pp.Literal("E)") | pp.Literal("F)"))) ) ).set_parse_action(_strip_block)
内容的提问来源于stack exchange,提问作者Michael Henry
相关产品推荐
相关产品推荐

