0

I'm having a hard time writing a regexp pattern to parse lines in a file. On each line there is a key, an equal sign and 0 or more values (if there are more than one they are seperated by a comma).

I'm using this pattern to split every lines:

^([A-Z_]*)[ \t]*=[ \t]*\"([A-Z\:0-9\'\-\! ]*)\"(?:,[ \t]*\"([A-Z\:0-9\'\-\! ]*)\")*$

The problem I have is that it only returns the key, the first and the last value. I need it to return every values.

I'm writing this class for Python 3, and I'm using re.groups() to split the line.

I'm providing the input file, the console output and the class' code.

Input file:

City = "Urban Recovery", "Urban Mop-up Operation", "The Oncoming Darkness", "Arks Ship Fire Swirl"
Forest = "Subdue Fang Banther", "With Wind and Rain"
Caves = "Cave", "Volcanic Guerillas"
Desert = "Desert Guerillas"
Tundra =
Skyland = "Rampaging Malice", "Chrome"
Tunnels = "Mega Mecha awakening"
Ruins = 
Coast = "Beach Wars!"
Quarry = 
Space = "Profound Darkness' Kin: Elder", "Raging Dark Arms", "Approaching Dark Arms", "Utterly Profound", "Falz", "Dark Falz"
Event = "Merry Christmas on Ice", "Trick or Treat", "A Boisterous White Day", "Where's the Chocolate"

Console output:

('City', 'Urban Recovery', 'Arks Ship Fire Swirl') <class 'tuple'>
('Forest', 'Subdue Fang Banther', 'With Wind and Rain') <class 'tuple'>
('Caves', 'Cave', 'Volcanic Guerillas') <class 'tuple'>
('Desert', 'Desert Guerillas', None) <class 'tuple'>
('Skyland', 'Rampaging Malice', 'Chrome') <class 'tuple'>
('Tunnels', 'Mega Mecha awakening', None) <class 'tuple'>
('Coast', 'Beach Wars!', None) <class 'tuple'>
('Space', "Profound Darkness' Kin: Elder", 'Dark Falz') <class 'tuple'>

Code:

import re

class QuestSelector:
    def __init__(self, filename):
        self.quests = []
        self.filename = filename
        self.parser = re.compile("^([A-Z_]*)[ \t]*=[ \t]*\"([A-Z\:0-9\'\-\! ]*)\"(?:,[ \t]*\"([A-Z\:0-9\'\-\! ]*)\")*$", re.I)

        self.Load()

    def Load(self):
        try:
            file = open(self.filename)
            for line in file.readlines():
                grp = self.parser.match(line[:-1])
                if (grp):
                    tup = grp.groups()
                    print("{} {}".format(tup, str(type(tup))))
        except IOError:
            print("Could not read {}.".format(file))
        except FileNotFoundError:
            print("Could not open {}.".format(file))

    def Available(self):
        print(self.quests)

    def criticalError(self, code):
            print("This was a critical error, will now exit({})".format(code))
            exit(code)

Thanks for helping.

  • 1
    Docs for `re.group()`: [***If a group matches multiple times, only the last match is accessible***](http://docs.python.org/2/library/re.html#re.MatchObject.group). There are other ways though, e.g. [One](http://stackoverflow.com/questions/5060659/python-regexes-how-to-access-multiple-matches-of-a-group), [Two](http://stackoverflow.com/questions/3075518/multiple-results-from-one-subgroup) – jedwards Sep 27 '13 at 01:32
  • 1
    From this example, I don't think you need a regex; just `split` by `=` and `,`, and `strip` `"` and spaces. – Waleed Khan Sep 27 '13 at 01:35

1 Answers1

1

You can accomplish this much quicker using String.split(), String.strip() and some list comprehension.

in_text = """City = "Urban Recovery", "Urban Mop-up Operation", "The Oncoming Darkness", "Arks Ship Fire Swirl"
Forest = "Subdue Fang Banther", "With Wind and Rain"
Caves = "Cave", "Volcanic Guerillas"
Desert = "Desert Guerillas"
Tundra =
Skyland = "Rampaging Malice", "Chrome"
Tunnels = "Mega Mecha awakening"
Ruins = 
Coast = "Beach Wars!"
Quarry = 
Space = "Profound Darkness' Kin: Elder", "Raging Dark Arms", "Approaching Dark Arms", "Utterly Profound", "Falz", "Dark Falz"
Event = "Merry Christmas on Ice", "Trick or Treat", "A Boisterous White Day", "Where's the Chocolate" """

for line in in_text.split("\n"):
    key,vals = line.split("=")
    key = key.strip()
    vals = [x.strip() for x in vals.split(",")]
    print key," : ",vals

Gives:

City  :  ['"Urban Recovery"', '"Urban Mop-up Operation"', '"The Oncoming Darkness"', '"Arks Ship Fire Swirl"']
Forest  :  ['"Subdue Fang Banther"', '"With Wind and Rain"']
Caves  :  ['"Cave"', '"Volcanic Guerillas"']
Desert  :  ['"Desert Guerillas"']
Tundra  :  ['']
Skyland  :  ['"Rampaging Malice"', '"Chrome"']
Tunnels  :  ['"Mega Mecha awakening"']
Ruins  :  ['']
Coast  :  ['"Beach Wars!"']
Quarry  :  ['']
Space  :  ['"Profound Darkness\' Kin: Elder"', '"Raging Dark Arms"', '"Approaching Dark Arms"', '"Utterly Profound"', '"Falz"', '"Dark Falz"']
Event  :  ['"Merry Christmas on Ice"', '"Trick or Treat"', '"A Boisterous White Day"', '"Where\'s the Chocolate"']