Question

my data is located in a .txt file (no, I can't change it to a different format) and it looks like this:

varaiablename = value
something = thisvalue
youget = the_idea

Here is my code so far (taken from the examples in Pyparsing):

from pyparsing import Word, alphas, alphanums, Literal, restOfLine, OneOrMore, \
empty, Suppress, replaceWith

input = open("text.txt", "r")
src = input.read()

# simple grammar to match #define's
ident = Word(alphas + alphanums + "_")
macroDef = ident.setResultsName("name") + "= " + ident.setResultsName("value") + Literal("#") + restOfLine.setResultsName("desc")
for t,s,e in macroDef.scanString(src):
print t.name,"=", t.value

So how can I tell my script to edit a specific value for a specific variable?
Example:
I want to change the value of variablename, from value to new_value. So essentially variable = (the data we want to edit).

I probably should make it clear that I don't want to go directly into the file and change the value by changing value to new_value but I want to parse the data, find the variable and then give it a new value.

Was it helpful?

Solution

For this task you do not need to use special utility or module What you need is reading lines and spliting them in list, so first index is left and second index is right side. If you need these values later you might want to store them in dictionary.

Well here is simple way, for somebody new in python. Uncomment lines whit print to use it as debug.

f=open("conf.txt","r")
txt=f.read() #all text is in txt
f.close()

fwrite=open("modified.txt","w")
splitedlines = txt.splitlines():
#print splitedlines 
for line in splitedlines:
    #print line
    conf = line.split('=')
    #conf[0] is what it is on left and conf[1] is what it is on right
    #print conf
    if conf[0] == "youget":
        #we get this
        conf[1] = "the_super_idea" #the_idea is now the_super_idea
    #join conf whit '=' and write
    newline = '='.join(conf)
    #print newline
    fwrite.write(newline+"\n")

fwrite.close()

OTHER TIPS

Even though you have already selected another answer, let me answer your original question, which was how to do this using pyparsing.

If you are trying to make selective changes in some body of text, then transformString is a better choice than scanString (although scanString or searchString are fine for validating your grammar expression by looking for matching text). transformString will apply token suppression or parse action modifications to your input string as it scans through the text looking for matches.

# alphas + alphanums is unnecessary, since alphanums includes all alphas
ident = Word(alphanums + "_")
# I find this shorthand form of setResultsName is a little more readable
macroDef = ident("name") + "=" + ident("value")

# define values to be updated, and their new values
valuesToUpdate = {
    "variablename" : "new_value"
    }

# define a parse action to apply value updates, and attach to macroDef
def updateSelectedDefinitions(tokens):
    if tokens.name in valuesToUpdate:
        newval = valuesToUpdate[tokens.name]
        return "%s = %s" % (tokens.name, newval)
    else:
        raise ParseException("no update defined for this definition")
macroDef.setParseAction(updateSelectedDefinitions)

# now let transformString do all the work!
print macroDef.transformString(src)

Gives:

variablename = new_value
something = thisvalue
youget = the_idea

Actually, you should have a look at the config parser module Which parses exactly your syntax (you need only to add [section] at the beginning).

If you insist on your implementation, you can create a dictionary :

dictt = {}
for t,s,e in macroDef.scanString(src):
   dictt[t.name]= t.value
dictt[variable]=new_value

ConfigParser

import ConfigParser

config = ConfigParser.RawConfigParser()
config.read('example.txt')

variablename = config.get('variablename', 'float')

It'll yell at you if you don't have a [section] header, though, but it's ok, you can fake one.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top