Backreferences in python ?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Pankaj

    Backreferences in python ?


    I have something like below in perl and i am searching for equivalent
    in python:

    ::: Perl :::
    ***********
    while( <FILEHANDLE> )
    {

    line = $_;

    pattern = "printf\( \"$lineNo \" \),";

    line =~ s/"for(.*)\((*.)\ ;(.*)/for$1\($pattern $2\;$3/g;
    }

    This is used to

    search for : for ( i = 0; i < 10; i++)
    Replace with: for( printf( "10" ), i =0; i < 10; i++)
    Where 10 is the line no.

    *************** *************** **********
    What i tried in python was::
    *************** *************** **********

    f = open( "./1.c", "r")
    fNew = open( "./1_new.c", "w")
    for l in f:
    print l
    lineno = lineno + 1
    strToFind = "for\((.*)\;(.* )"

    ## For Converting int to string, i.e. line no. to string
    lineNoClone = lineno

    pattern = "printf(\"" + str( lineNoClone) + "\"),"

    print pattern

    strToReplace = "for\(" + pattern + "\1\;"

    fNew.write( l.replace( strToFind, strToReplace) )

    print l

    fNew.close()

  • Gerhard Häring

    #2
    Re: Backreferences in python ?

    Pankaj wrote:[color=blue]
    > [...]
    > *************** *************** **********
    > What i tried in python was::
    > *************** *************** **********
    >
    > f = open( "./1.c", "r")
    > fNew = open( "./1_new.c", "w")
    > for l in f:
    > print l
    > lineno = lineno + 1
    > strToFind = "for\((.*)\;(.* )"
    > [...][/color]

    Regular expressions are not handled automatically in Python the way you
    apparently think they are.

    In Python, you will need to use the "re" module:

    Source code: Lib/re/ This module provides regular expression matching operations similar to those found in Perl. Both patterns and strings to be searched can be Unicode strings ( str) as well as 8-...


    -- Gerhard

    Comment

    • Pankaj

      #3
      Re: Backreferences in python ?

      My tries have with re have not yielded results::


      {
      strToFind = 'for*;*'

      ## Converting int to string, i.e. line no. to string
      lineNoClone = lineno

      pattern = "printf(\"" + str( lineNoClone) + "\"),"

      regObj = re.compile( strToFind)

      m = regObj.search( l)


      if ( m != None ) :
      subStrPattern1_ hasInitializati on = "\1"
      #m.group(1)

      subStrPattern2_ hasRestTillEnd = "\2"
      #m.group(2)

      strToReplace = "for(" + pattern +
      subStrPattern1_ hasInitializati on + ";" + subStrPattern2_ hasRestTillEnd
      fNew.write( regObj.sub( strToFind, strToReplace ) )
      else:
      fNew.write( l)
      }


      Here problem is , i am not getting backreferences using \1 and \2

      The string : for( i =0; i < 10; i++)

      is getting replace by: for *;* {

      I don't believe this, they have given that \1 and \2 store
      backreferences, then where r they??

      Comment

      • Pankaj

        #4
        Re: Backreferences in python ?

        I got my answer

        if ( m != None ) :
        subStrPattern1_ hasInitializati on = m.group(1)


        subStrPattern2_ hasRestTillEnd = m.group(2)

        str = subStrPattern1_ hasInitializati on +
        subStrPattern2_ hasRestTillEnd
        strToReplace = "for(" + pattern + str


        This gave me my solution

        But to tell u, i have not got that, why i should concatenate and then
        only place it . while i was trying the same thing by concatenation it
        straight to replace string, it was not working

        Any body has reasons ???

        Comment

        • Duncan Booth

          #5
          Re: Backreferences in python ?

          Pankaj wrote:
          [color=blue]
          > Here problem is , i am not getting backreferences using \1 and \2
          >[/color]

          You wrote:[color=blue]
          > subStrPattern1_ hasInitializati on = "\1"[/color]

          "\1" is the way to create a string containing a control-A character. What
          you actually wanted was a string containing a backslash and a "1", so you
          need either:

          "\\1"

          or

          r"\1"

          Try using the print statement to see what all those strings you are
          creating actually contain.

          Comment

          • Paul McGuire

            #6
            Re: Backreferences in python ?

            "Pankaj" <pankajgode@gma il.com> wrote in message
            news:1138029493 .503320.178550@ o13g2000cwo.goo glegroups.com.. .[color=blue]
            >
            > I have something like below in perl and i am searching for equivalent
            > in python:
            >
            > ::: Perl :::
            > ***********
            > while( <FILEHANDLE> )
            > {
            >
            > line = $_;
            >
            > pattern = "printf\( \"$lineNo \" \),";
            >
            > line =~ s/"for(.*)\((*.)\ ;(.*)/for$1\($pattern $2\;$3/g;
            > }
            >
            > This is used to
            >
            > search for : for ( i = 0; i < 10; i++)
            > Replace with: for( printf( "10" ), i =0; i < 10; i++)
            > Where 10 is the line no.
            >[/color]

            Here is a solution using pyparsing instead of re's. You're already used to
            re's from using Perl, so you may be more comfortable using that tool in
            Python as well. But pyparsing has some builtin features for pattern
            matching, calling out to callback routines during parsing, and a lineno
            function to report the current line number, all wrapped up in a simple
            transformString method call.

            Download pyparsing at http://pyparsing.sourceforge.net.

            -- Paul


            from pyparsing import Keyword,SkipTo, lineno,cStyleCo mment

            # define grammar for a for statement
            for_ = Keyword("for")
            forInitializer = SkipTo(';').set ResultsName("in itializer")
            forStmt = for_ + "(" + forInitializer + ';'

            # ignore silly comments
            forStmt.ignore( cStyleComment)

            # setup a parse action that will insert line numbers
            # parse actions are all called with 3 args:
            # - the original string being parsed
            # - the current parse location where the match occurred
            # - the matching tokens
            # if a value is returned from this function, transformString will
            # insert it in place of the original content
            def insertPrintStat ement(st,loc,to ks):
            lineNumber = lineno(loc,st)
            if toks[0]:
            return r'print("%d\n") , %s' % (lineNumber,tok s[0])
            else:
            return r'print("%d\n") ' % lineNumber
            forInitializer. setParseAction( insertPrintStat ement)

            # transform some code
            # this is how you would read in a whole file as a single string
            #testdata = file(inputfilen ame).read()
            # to read the entire file into a list of strings, do:
            #testdata = file(inputfilen ame).readlines( )
            # for now, just fake some source code
            testData = """
            for(i = 0; i <= 100; ++i)
            {
            /* some stuff */
            }

            for (;;;)
            {
            /* do this forever */
            }

            /* this for has been commented out
            for(a = -1; a < 0; a++)
            */

            """

            # use the grammar and the associated parse action to
            # transform the source code
            print forStmt.transfo rmString(testDa ta)

            --------------------------
            Gives:
            for(print("2\n" ), i = 0; i <= 100; ++i)
            {
            /* some stuff */
            }

            for(print("7\n" );;;)
            {
            /* do this forever */
            }

            /* this for has been commented out
            for(a = -1; a < 0; a++)
            */



            Comment

            • Giovanni Bajo

              #7
              Re: Backreferences in python ?

              Pankaj wrote:
              [color=blue][color=green][color=darkred]
              >>>> Perl :::[/color][/color]
              > ***********
              > while( <FILEHANDLE> )
              > {
              >
              > line = $_;
              >
              > pattern = "printf\( \"$lineNo \" \),";
              >
              > line =~ s/"for(.*)\((*.)\ ;(.*)/for$1\($pattern $2\;$3/g;
              > }
              >
              > This is used to
              >
              > search for : for ( i = 0; i < 10; i++)
              > Replace with: for( printf( "10" ), i =0; i < 10; i++)
              > Where 10 is the line no.[/color]


              import re
              import fileinput

              for L in fileinput.input (inplace=True):
              pattern = 'printf("%d"),' % input.filelinen o()
              L = re.sub(r"for(.* )\((*.)\;(.*)", r"for\1\(%s\2;\ 3" % pattern, L)
              print L,

              or something
              --
              Giovanni Bajo


              Comment

              • Sion Arrowsmith

                #8
                Re: Backreferences in python ?

                Pankaj <pankajgode@gma il.com> wrote:[color=blue]
                >search for : for ( i = 0; i < 10; i++)
                >Replace with: for( printf( "10" ), i =0; i < 10; i++)
                >Where 10 is the line no.[/color]
                [color=blue]
                >f = open( "./1.c", "r")
                >fNew = open( "./1_new.c", "w")
                >for l in f:
                > print l
                > lineno = lineno + 1
                > strToFind = "for\((.*)\;(.* )"[/color]
                [etc.][color=blue]
                >search for : for ( i = 0; i < 10; i++)
                >Replace with: for( printf( "10" ), i =0; i < 10; i++)[/color]

                Ah, the dangers of thinking of all string manipulation as requiring
                regexps, thanks to their ubiquity in Perl. Observe:[color=blue]
                >search for : for ( i = 0; i < 10; i++)
                >Replace with: for( printf( "10" ), i = 0; i < 10; i++)[/color]

                All you need is:
                strToFind = "for ("
                strToReplace = 'for (printf( "+str(lineno)+' " ),'
                # Note the use of '' to avoid the need to escape the "s
                fNew.write(l.re place(strToFind , strToReplace)

                (OK, maybe you do need the regexp if you've got any "for (;" loops,
                or inconsitencies as to whether it's "for(" or "for (". But if a
                simple string replace will do the job, use it.)

                --
                \S -- siona@chiark.gr eenend.org.uk -- http://www.chaos.org.uk/~sion/
                ___ | "Frankly I have no feelings towards penguins one way or the other"
                \X/ | -- Arthur C. Clarke
                her nu becomeþ se bera eadward ofdun hlæddre heafdes bæce bump bump bump

                Comment

                Working...