2

Based on ConfigParser module how can I filter out and throw every comments from an ini file?

import ConfigParser
config = ConfigParser.ConfigParser()
config.read("sample.cfg")

for section in config.sections():
    print section
    for option in config.options(section):
        print option, "=", config.get(section, option)

eg. in the ini file below the above basic script prints out the further comments lines as well like:

something  = 128     ; comment line1
                      ; further comments 
                       ; one more line comment

What I need is having only the section names and pure key-value pairs inside them without any comments. Does ConfigParser handles this somehow or should I use regexp...or? Cheers

Paolo Tedesco
  • 55,237
  • 33
  • 144
  • 193
  • 1
    What does "throw out" mean? Please provide a clear statement of what you're really trying to do -- why do you need to "throw out" data from a file? Where does it go? What's left behind? – S.Lott Feb 19 '09 at 12:08

5 Answers5

5

according to docs lines starting with ; or # will be ignored. it doesn't seem like your format satisfies that requirement. can you by any chance change format of your input file?

edit: since you cannot modify your input files, I'd suggest pre-parsing them with something along the lines:

tmp_fname = 'config.tmp'
with open(config_file) as old_file:
    with open(tmp_fname, 'w') as tmp_file:
        tmp_file.writelines(i.replace(';', '\n;') for i in old_lines.readlines())
# then use tmp_fname with ConfigParser

obviously if semi-colon is present in options you'll have to be more creative.

SilentGhost
  • 307,395
  • 66
  • 306
  • 293
3

Best way is to write a commentless file subclass:

class CommentlessFile(file):
    def readline(self):
        line = super(CommentlessFile, self).readline()
        if line:
            line = line.split(';', 1)[0].strip()
            return line + '\n'
        else:
            return ''

You could use it then with configparser (your code):

import ConfigParser
config = ConfigParser.ConfigParser()
config.readfp(CommentlessFile("sample.cfg"))

for section in config.sections():
    print section
    for option in config.options(section):
        print option, "=", config.get(section, option)
nosklo
  • 217,122
  • 57
  • 293
  • 297
2

Python 3 comes with a build-in solution: The class configparser.RawConfigParser has constructor argument inline_comment_prefixes. Example:

class MyConfigParser(configparser.RawConfigParser):
    def __init__(self):
      configparser.RawConfigParser.__init__(self, inline_comment_prefixes=('#', ';'))
gecco
  • 17,969
  • 11
  • 51
  • 68
2

It seems your comments are not on lines that start with the comment leader. It should work if the comment leader is the first character on the line.

sykora
  • 96,888
  • 11
  • 64
  • 71
  • Thanks, but unfortunately I am not allowed to modify the input ini file.In this format of ini file as I noticed all the comment lines are appended to the value part of last key - except the first comment line (right after value) which is dropped indeed. –  Feb 19 '09 at 11:53
  • In fact my task is to compare two ini files (every significant part except comments) –  Feb 19 '09 at 11:54
  • Then you'll probably have to create a temporary file and/or use ConfigParser.readfp() to scrap the comments. – sykora Feb 19 '09 at 12:01
1

As the doc said: "(For backwards compatibility, only ; starts an inline comment, while # does not.)" So use ";" and not "#" for inline comments. It is working well for me.

Pierre Thibault
  • 1,895
  • 2
  • 19
  • 22