2017-03-03 68 views
0

我有,我想使用Python ConfigParser库来解析形式使用ConfigParser读取非标准配置文件

# foo.conf 

[section1] 
foo=bar 
buzz=123 

[section2] 
line1 
line2 
line3 

的配置文件。请注意,section2不包含键/值对,而是包含一些原始文本。我希望能够将所有(原始)section2的内容读取到变量中。

ConfigParser是否允许我读取这个文件,或者它的某个类可以通过简单的方式进行子类化?

使用标准

import ConfigParser 

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

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

+0

ConfigParser *点是*,它是一个(相对)标准格式。你的格式并不适合他们的方案。 –

+0

你想写什么变量?如果您改为'variable = line1'并继续以下几行,它将正常工作。 –

+0

也许你可以将所有这些“行”折叠为一个单独的变量,如'section2 = line1,line2,line3'。它也建议[这里](http://stackoverflow.com/questions/335695/lists-in-configparser)。当然这取决于你的具体需求。 – farsil

回答

1

您可以尝试使用io适配器以适合ConfigParser的格式转换输入文件。一种方法是转换既不是空行也不是注释行的普通行,也不在linei=original_line中的行不是key=value行,其中每行增加i,并在每个行中从1开始。

一个可能的代码可能是:

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 "" 

这样,您可以与您现有的文件中使用而无需改变任何东西:

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

据我所知,ConfigParser不能做到这一点:

的ConfigParser类实现一个基本的配置文件解析器 这种语言提供了一种类似于你在上找到的结构210个Microsoft Windows INI文件。

看来你的conf文件不是一个基本的配置文件,所以也许有两种方法可以解析这个conf文件。

  • 读取conf文件并对其进行修改。
  • 生成有效的配置文件。
相关问题