449,188 Members | 1,337 Online Need help? Post your question and get tips & solutions from a community of 449,188 IT Pros & Developers. It's quick & easy.

 P: n/a I'm trying to develop a little script that does some string manipulation. I have some few hundred strings that currently look like this: cond(a,b,c) and I want them to look like this: cond(c,a,b) but it gets a little more complicated because the conds themselves may have conds within, like the following: cond(0,cond(c,cond(e,cond(g,h,(a= d)) OUTPUT: whole string is: (a,b,(abs(c) the new string is:cond((abs(c,a,b) Can anyone help me with the regular expression? Is this even the best approach to take? Anyone have any thoughts? Thanks for your time! Aug 23 '06 #1
4 Replies

 P: n/a cond(a,b,c) > and I want them to look like this: cond(c,a,b) but it gets a little more complicated because the conds themselves may have conds within, like the following: cond(0,cond(c,cond(e,cond(g,h,(a

 P: n/a MooMaster wrote: I'm trying to develop a little script that does some string manipulation. I have some few hundred strings that currently look like this: cond(a,b,c) and I want them to look like this: cond(c,a,b) but it gets a little more complicated because the conds themselves may have conds within, like the following: cond(0,cond(c,cond(e,cond(g,h,(a= d)) OUTPUT: whole string is: (a,b,(abs(c) the new string is:cond((abs(c,a,b) Can anyone help me with the regular expression? Is this even the best approach to take? Anyone have any thoughts? Thanks for your time! You're gonna want a parser for this. pyparsing or spark would suffice. However, since it looks like your source strings are valid python you could get some traction out of the tokenize standard library module: from tokenize import generate_tokens from StringIO import StringIO s = 'cond(-1,1,f)*((float(e)*(2**4))+(float(d)*8)+(float(c)*4 )+(float(b)*2)+float(a))' for t in generate_tokens(StringIO(s).readline): print t, Prints: cond ( - 1 , 1 , f ) * ( ( float ( e ) * ( 2 ** 4 ) ) + ( float ( d ) * 8 ) + ( float ( c ) * 4 ) + ( float ( b ) * 2 ) + float ( a ) ) Once you've got that far the rest should be easy. :) Peace, ~Simon http://pyparsing.wikispaces.com/ http://pages.cpsc.ucalgary.ca/~aycock/spark/ http://docs.python.org/lib/module-tokenize.html Aug 23 '06 #3

 P: n/a "MooMaster" Pyparsing makes this a fairly tractable problem. The hardest part is defining the valid contents of a relational and arithmetic expression, which may be found within the arguments of your cond(a,b,c) constructs. Not guaranteeing this 100%, but it did convert your pathologically nested example on the first try. -- Paul ---------- from pyparsing import * ident = ~Literal("cond") + Word(alphas) number = Combine(Optional("-") + Word(nums) + Optional("." + Word(nums))) arithExpr = Forward() funcCall = ident+"("+delimitedList(arithExpr)+")" operand = number | funcCall | ident binop = oneOf("+ - * /") arithExpr << ( ( operand + ZeroOrMore( binop + operand ) ) | ("(" + arithExpr + ")" ) ) relop = oneOf("< == <= >= != <>") condDef = Forward() simpleCondExpr = arithExpr + ZeroOrMore( relop + arithExpr ) | condDef multCondExpr = simpleCondExpr + "*" + arithExpr condExpr = Forward() condExpr << ( simpleCondExpr | multCondExpr | "(" + condExpr + ")" ) def reorderArgs(t): return "cond(" + ",".join(["".join(t.arg3), "".join(t.arg1), "".join(t.arg2)]) + ")" condDef << ( Literal("cond") + "(" + Group(condExpr).setResultsName("arg1") + "," + Group(condExpr).setResultsName("arg2") + "," + Group(condExpr).setResultsName("arg3") + ")" ).setParseAction( reorderArgs ) tests = [ "cond(a,b,c)", "cond(1>2,b,c)", "cond(-1,1,f)*((float(e)*(2**4))+(float(d)*8)+(float(c)*4 )+(float(b)*2)+floa t(a))", "cond(a,b,(abs(c) >= d))", "cond(0,cond(c,cond(e,cond(g,h,(a",condExpr.transformString(t) ---------- Prints: cond(a,b,c) -cond(c,a,b) cond(1>2,b,c) -cond(c,1>2,b) cond(-1,1,f)*((float(e)*(2**4))+(float(d)*8)+(float(c)*4 )+(float(b)*2)+float (a)) -> cond(f,-1,1)*((float(e)*(2**4))+(float(d)*8)+(float(c)*4)+ (float(b)*2)+float (a)) cond(a,b,(abs(c) >= d)) -cond((abs(c)>=d),a,b) cond(0,cond(c,cond(e,cond(g,h,(a cond((a<1),0,cond((a

 P: n/a MooMaster Wrote: I'm trying to develop a little script that does some string manipulation. I have some few hundred strings that currently look like this: cond(a,b,c) and I want them to look like this: cond(c,a,b) I zoned out on your question and created a very simple flipper. Although it will not solve your problem maybe someone looking for a simpler version may find it useful as a starting point. I hope it proves useful. I'll post my simple flipper here: s = 'cond(1,savv(grave(3,2,1),y,x),maxx(c,b,a),0)' def argFlipper(s): ''' take a string of arguments and reverse'em e.g. >>cond(1,savv(grave(3,2,1),y,x),maxx(c,b,a),0) -cond(0,maxx(a,b,c),savv(x,y,grave(1,2,3)),1) ''' count = 0 keyholder = {} while 1: if s.find('(') 0: count += 1 value = '%sph' + '%d' % count tempstring = [x for x in s] startindex = s.rfind('(') limitindex = s.find(')', startindex) argtarget = s[startindex + 1:limitindex].split(',') argreversed = ','.join(reversed(argtarget)) keyholder[value] = '(' + argreversed + ')' tempstring[startindex:limitindex + 1] = value s = ''.join(tempstring) else: while count and keyholder: s = s.replace(value, keyholder[value]) count -= 1 value = '%sph' + '%d' % count return s print argFlipper(s) Aug 24 '06 #5

### This discussion thread is closed

Replies have been disabled for this discussion. 