如何用pyparsing仅解析以pci开头的行并跳过其他行?
问题分析与解决方案
现有代码的问题
- 非PCI行匹配规则无效:
Regex(r"(?!pci)")是零宽负向前瞻,仅检查位置不匹配任何字符,Suppress它无法跳过整行非PCI内容,解析器遇到非PCI行时会因无法匹配而终止,得不到有效结果。 - PCI设备名匹配规则错误:
Word("pci" + nums)将"pci"和数字作为允许的初始字符集,会匹配c24、i25这类不符合要求的字符串,而非严格以"pci"开头的设备名。 - 未处理多行重复匹配:原语法仅定义单次匹配,未声明需遍历所有行,无法处理多行文本的解析需求。
正确实现方式
方式一:先过滤行再解析(简单直观)
先读取文件并过滤出以"pci"开头的行,再用pyparsing解析每行内容:
from pyparsing import Word, nums, alphanums, Group, Combine, Literal # 正确定义PCI行语法:匹配pci前缀+数字,再匹配后面的标识 pci_grammar = Group(Combine(Literal("pci") + Word(nums)) + Word(alphanums + "-")) with open("foo.txt", "r") as f: for line in f: stripped_line = line.strip() if stripped_line.startswith("pci"): result = pci_grammar.parseString(stripped_line) print(result)
方式二:用pyparsing语法直接处理整文本
定义完整的语法规则,让解析器自动跳过非PCI行,提取目标内容:
from pyparsing import Word, nums, alphanums, Group, Combine, Literal, Suppress, Regex, OneOrMore, re # 匹配完整的PCI行 pci_line = Group(Combine(Literal("pci") + Word(nums)) + Word(alphanums + "-")) # 匹配并跳过整行非PCI内容(启用多行模式) non_pci_line = Suppress(Regex(r"^(?!pci).*$", re.MULTILINE)) # 定义全局语法:重复匹配PCI行或非PCI行 full_grammar = OneOrMore(pci_line | non_pci_line) with open("foo.txt", "r") as f: parsed_data = full_grammar.parseString(f.read()) print(parsed_data)
输出结果
两种方式都会得到如下解析结果:
['pci24', 'u2480-L0'] ['pci25', 'h6045-L0'] ['pci26', 'h6045-L1']
内容的提问来源于stack exchange,提问作者Jai
相关产品推荐
相关产品推荐

