Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I don't see where's the problem.</p> <p>What about the following code ?</p> <pre><code>import re pat = '(=\s*).+?(?=\s*(#|$))' rgx = re.compile(pat,re.MULTILINE) su = '''log_File = a.log ### the path for log log_File = a.log log_File = a.log''' print su print print rgx.sub('\\1Hello',su) </code></pre> <p>.</p> <h3>EDIT</h3> <p>.</p> <p>I have seen where's the problem !</p> <p>As I wrote it, I don't think that the problem can be simply solved by only regex or a relatively simple function, because changing the right-part of an assignement (attribute called <strong>value</strong> in the AST node of an assignement) without touching the possible comment requires a syntactic analyze to determine what is the left-part of an assignement (attribute called <strong>targets</strong> in an AST node of an assignement), what is the right-part and what is the possible comment in a line. And even if a line isn't an assignement instruction, a syntactic analyze is required to determine it.</p> <p>For such a task there's only the module <code>ast</code>, which <em>helps Python applications to process trees of the Python abstract syntax grammar</em>, that can provide the tools to achieve the goal, in my opinion.</p> <p>Here's the code I succeeded to write on this idea:</p> <pre><code>import re,ast from sys import exit su = '''# it's nothing import re def funcg(a,b):\r print a*b + 900 x = "abc#ghi"\t\t# comment k = 103 dico["abc#12"] = [(x,x//3==0) for x in xrange(25) if x !=12] dico["ABC#12"] = 45 # comment a = 'lulu#88' dico["mu=$*"] = 'mouth#30' #ohoh log_File = a.log y = b.log ### x = a.log ''' print su def subst_assign_val_in_line(line,b0,repl): assert(isinstance(b0,ast.AST)) coloffset = b0.value.col_offset VA = line[coloffset:] try: yy = compile(VA+'\n',"-expr-",'eval') except: # because of a bug of ast in computing VA coloffset = coloffset - 1 VA = line[coloffset:] yy = compile(VA+'\n',"-expr-",'eval') gen = ((i,c) for i,c in enumerate(VA) if c=='#') for i,c in gen: VAshort = VA[0:i] # &lt;== cuts in front of a # character try: yyi = compile(VAshort+'\n',"-exprshort-",'eval') except: pass else: if yy==yyi: return (line[0:coloffset] + repl + ' ' + line[coloffset+i:]) break else: print 'VA = line[%d:]' % coloffset print 'VA : %r' % VA print ' yy != yyi on:' print 'VAshort : %r' % VAshort raw_input(' **** UNIMAGINABLE CASE ***') else: return line[0:coloffset] + repl def subst_assigns_vals_in_text(text,repl, rgx = re.compile('\A([ \t]*)(.*)')): def yi(text): for line in text.splitlines(): head,line = rgx.search(line).groups() try: body = ast.parse(line,'line','exec').body except: yield head + line else: if isinstance(body,list): if len(body)==0: yield head + line elif len(body)==1: if type(body[0])==ast.Assign: yield head + subst_assign_val_in_line(line, body[0], repl) else: yield head + line else: print "list ast.parse(line,'line','exec').body has more than 1 element" print body exit() else: print "ast.parse(line,'line','exec').body is not a list" print body exit() return '\n'.join(yi(text)) print subst_assigns_vals_in_text(su,repl='Hello') </code></pre> <p>In fact, I wrote it accompanied with instructions <code>print</code> and the help of a personnal programm to display an AST tree in a readable manner (for me).<br> Here after is the code with instructions <code>print</code> only, to follow the process:</p> <pre><code>import re,ast from sys import exit su = '''# it's nothing import re def funcg(a,b):\r print a*b + 900 x = "abc#ghi"\t\t# comment k = 103 dico["abc#12"] = [(x,x//3==0) for x in xrange(25) if x !=12] dico["ABC#12"] = 45 # comment a = 'lulu#88' dico["mu=$*"] = 'mouth#30' #ohoh log_File = a.log y = b.log ### x = a.log ''' print su print '#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-' def subst_assign_val_in_line(line,b0,repl): assert(isinstance(b0,ast.AST)) print '\n%%%%%%%%%%%%%%%%\nline : %r' % line print '\nb0 == body[0]: ',b0 print '\nb0.value: ',b0.value print '\nb0.value.col_offset==',b0.value.col_offset coloffset = b0.value.col_offset VA = line[coloffset:] try: yy = compile(VA+'\n',"-expr-",'eval') except: # because of a bug of ast in computing VA coloffset = coloffset - 1 VA = line[coloffset:] yy = compile(VA+'\n',"-expr-",'eval') print 'VA = line[%d:]' % coloffset print 'VA : %r' % VA print ("yy = compile(VA+'\\n',\"-expr-\",'eval')\n" 'yy =='),yy gen = ((i,c) for i,c in enumerate(VA) if c=='#') deb = ("mwmwmwmwmwmwmwmwmwmwmwmwmwmwmwmwmwmwmwmw\n" " mwmwmwm '#' in VA mwmwmwm\n") for i,c in gen: print '%si == %d VA[%d] == %r' % (deb,i,i,c) deb = '' VAshort = VA[0:i] # &lt;== cuts in front of a # character print ' VAshort = VA[0:%d] == %r' % (i,VAshort) try: yyi = compile(VAshort+'\n',"-exprshort-",'eval') except: print " compile(%r+'\\n',\"-exprshort-\",'eval') gives error" % VAshort else: print (" yyi = compile(VAshort+'\\n',\"-exprshort-\",'eval')\n" ' yyi =='),yy if yy==yyi: print ' yy==yyi Real value of assignement found' print "mwmwmwmwmwmwmwmwmwmwmwmwmwmwmwmwmwmwmwmw" return (line[0:coloffset] + repl + ' ' + line[coloffset+i:]) break else: print 'VA = line[%d:]' % coloffset print 'VA : %r' % VA print ' yy != yyi on:' print 'VAshort : %r' % VAshort raw_input(' **** UNIMAGINABLE CASE ***') else: return line[0:coloffset] + repl def subst_assigns_vals_in_text(text,repl, rgx = re.compile('\A([ \t]*)(.*)')): def yi(text): for line in text.splitlines(): raw_input('\n\npause') origline = line head,line = rgx.search(line).groups() print ('#########################################\n' '#########################################\n' 'line : %r\n' 'cut line : %r' % (origline,line)) try: body = ast.parse(line,'line','exec').body except: yield head + line else: if isinstance(body,list): if len(body)==0: yield head + line elif len(body)==1: if type(body[0])==ast.Assign: yield head + subst_assign_val_in_line(line, body[0], repl) else: yield head + line else: print "list ast.parse(line,'line','exec').body has more than 1 element" print body exit() else: print "ast.parse(line,'line','exec').body is not a list" print body exit() #in place of return '\n'.join(yi(text)) , to print the output def returning(text): for output in yi(text): print 'output : %r' % output yield output return '\n'.join(returning(text)) print '\n\n\n%s' % subst_assigns_vals_in_text(su,repl='Hello') </code></pre> <p>I don't give explanations because it would be too long to explain the structure of the AST tree of a code created by <code>ast.parse()</code>. I xwill give some lights on my code if asked</p> <p><strong>NB</strong> there's a bug in the functionning of <code>ast.parse()</code> when it gives the line and column at which begins certain nodes, so I was obliged to correct that byadditional lines of instructions.<br> For example, it gives a false result on a list comprehension. </p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload