简体   繁体   English

使用ConfigParser读取非标准配置文件

[英]Using ConfigParser to read non-standard config files

I am having a config file of the form 我有以下形式的配置文件

# foo.conf

[section1]
foo=bar
buzz=123

[section2]
line1
line2
line3

that I want to parse using the Python ConfigParser library. 我想使用Python ConfigParser库进行解析。 Note that section2 does not contain key/value pairs but some raw text instead. 请注意, section2不包含键/值对,而是包含一些原始文本。 I would like to have a possibility to read all (raw) content of section2 to a variable. 我想有可能将section2所有(原始)内容读入一个变量。

Does ConfigParser allow me to read this file or can one of its classes be subclassed in an easy manner to do so? ConfigParser是否允许我读取此文件,或者可以通过一种简单的方式将其子类进行子类化吗?

Using the standard 使用标准

import ConfigParser

config = ConfigParser.ConfigParser()
config.read('foo.conf')

yields ConfigParser.ParsingError: File contains parsing errors: foo.conf 产生ConfigParser.ParsingError: File contains parsing errors: foo.conf

You could try to use an io adapter to transform the input file in a format suitable for ConfigParser. 您可以尝试使用io适配器以适合ConfigParser的格式转换输入文件。 A way for that would be to tranform plain line that are neither empty line, nor comment line, nor section lines not key=value line in linei=original_line , where i is increased at each line and starts at 1 in each section. 一种方法是转换既不是空行,也不是注释行,也不是linei=original_line key=value线的截面线,其中i在每条线处增加,并在每个节中以1开始。

A possible code could be: 可能的代码可能是:

class ConfParsAdapter(io.RawIOBase):
    @staticmethod
    def _confParsAdapter(fd):
        num=1
        rxsec = re.compile('\[.*\]( *#.*)?$')
        rxkv = re.compile('.+?=.*')
        rxvoid = re.compile('(#.*)?$')
        for line in fd:
            if rxsec.match(line.strip()):
                num=1
            elif rxkv.match(line) or rxvoid.match(line.strip()):
                pass
            else:
                line = 'line{}={}'.format(num, line)
                num += 1
            yield(line)

    def __init__(self, fd):
        self.fd = self._confParsAdapter(fd)
    def readline(self, hint = -1):
        try:
            return next(self.fd)
        except StopIteration:
            return ""

That way, you could use with your current file without changing anything in it: 这样,您可以使用当前文件而无需更改其中的任何内容:

>>> parser = ConfigParser.RawConfigParser()
>>> parser.readfp(ConfParsAdapter(open('foo.conf'))
>>> parser.sections()
['section1', 'section2']
>>> parser.items('section2')
[('line1', 'line1'), ('line2', 'line2'), ('line3', 'line3')]
>>> 

As far as I know,ConfigParser can not do this: 据我所知,ConfigParser无法做到这一点:

The ConfigParser class implements a basic configuration file parser language which provides a structure similar to what you would find on Microsoft Windows INI files. ConfigParser类实现一种基本的配置文件解析器语言,该语言提供的结构类似于您在Microsoft Windows INI文件中找到的结构。

It seems that your conf file is not a basic configuration file,so maybe two ways you can parse this conf file. 似乎您的conf文件不是基本的配置文件,因此可能有两种方法可以解析此conf文件。

  • Read the conf file and modify it. 读取conf文件并进行修改。
  • Generate a valid configuration file. 生成有效的配置文件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM