Regexp question.

classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

Regexp question.

Kyku-2
Hello All.

I'm rewriting lots of Visual Basic for Applications functions to PHP.
First of all I wanted to add dollar signs in front of variables in
parameter lists. Something like: "Function Foo(a, b, c)" to "Function
Foo($a, $b, $c)". I tried using /g flag to substitute all the parameters
in one go but Vim only changed the first  argument that didn't have $ in
front of it (for a single line that matched). That means that I had to
repeat the :%s.... angain for the second paramters etc.
The regex is:
  %s/\(Function.\{-}(.\{-}\)\(\<\w\+\)/\1$\2/gc
My questions is purely educational: could this be done in a one pass?
Thanks in advance.
Reply | Threaded
Open this post in threaded view
|

Re: Regexp question.

Charles E Campbell Jr
KWrzalik wrote:

> Hello All.
>
> I'm rewriting lots of Visual Basic for Applications functions to PHP.
> First of all I wanted to add dollar signs in front of variables in
> parameter lists. Something like: "Function Foo(a, b, c)" to "Function
> Foo($a, $b, $c)". I tried using /g flag to substitute all the
> parameters in one go but Vim only changed the first  argument that
> didn't have $ in front of it (for a single line that matched). That
> means that I had to repeat the :%s.... angain for the second paramters
> etc.
> The regex is:
>  %s/\(Function.\{-}(.\{-}\)\(\<\w\+\)/\1$\2/gc
> My questions is purely educational: could this be done in a one pass?
> Thanks in advance.
>

So long as the arguments are on the same line as "Function ...(", the
following should do the trick:

  :g/Function \h\w*\s*(/s/[(,]\s*\zs\(\h\w*\)/$\1/g

Regards,
Chip Campbell

Reply | Threaded
Open this post in threaded view
|

Re: Regexp question.

Justin Randall-2


--- "Charles E. Campbell, Jr." <[hidden email]> wrote:

> KWrzalik wrote:
>
> > Hello All.
> >
> > I'm rewriting lots of Visual Basic for Applications functions to PHP.
> > First of all I wanted to add dollar signs in front of variables in
> > parameter lists. Something like: "Function Foo(a, b, c)" to "Function
> > Foo($a, $b, $c)". I tried using /g flag to substitute all the
> > parameters in one go but Vim only changed the first  argument that
> > didn't have $ in front of it (for a single line that matched). That
> > means that I had to repeat the :%s.... angain for the second paramters
> > etc.
> > The regex is:
> >  %s/\(Function.\{-}(.\{-}\)\(\<\w\+\)/\1$\2/gc
> > My questions is purely educational: could this be done in a one pass?
> > Thanks in advance.
> >
>
> So long as the arguments are on the same line as "Function ...(", the
> following should do the trick:
>
>   :g/Function \h\w*\s*(/s/[(,]\s*\zs\(\h\w*\)/$\1/g
>
> Regards,
> Chip Campbell
>
>


__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around
http://mail.yahoo.com 
Reply | Threaded
Open this post in threaded view
|

Re: Regexp question.

Justin Randall-2
In reply to this post by Charles E Campbell Jr
:%s/Function\s*\(.*\)\s*(\s*\(.*\)\s*,\s*\(.*\)\s*,\s*\(.*\)\s*)\s*/Function \1( $\2,
$\3, $\4)

enjoy

--- "Charles E. Campbell, Jr." <[hidden email]> wrote:

> KWrzalik wrote:
>
> > Hello All.
> >
> > I'm rewriting lots of Visual Basic for Applications functions to PHP.
> > First of all I wanted to add dollar signs in front of variables in
> > parameter lists. Something like: "Function Foo(a, b, c)" to "Function
> > Foo($a, $b, $c)". I tried using /g flag to substitute all the
> > parameters in one go but Vim only changed the first  argument that
> > didn't have $ in front of it (for a single line that matched). That
> > means that I had to repeat the :%s.... angain for the second paramters
> > etc.
> > The regex is:
> >  %s/\(Function.\{-}(.\{-}\)\(\<\w\+\)/\1$\2/gc
> > My questions is purely educational: could this be done in a one pass?
> > Thanks in advance.
> >
>
> So long as the arguments are on the same line as "Function ...(", the
> following should do the trick:
>
>   :g/Function \h\w*\s*(/s/[(,]\s*\zs\(\h\w*\)/$\1/g
>
> Regards,
> Chip Campbell
>
>


__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around
http://mail.yahoo.com 
Reply | Threaded
Open this post in threaded view
|

Re: Regexp question.

Charles E Campbell Jr
Justin Randall wrote:

>:%s/Function\s*\(.*\)\s*(\s*\(.*\)\s*,\s*\(.*\)\s*,\s*\(.*\)\s*)\s*/Function \1( $\2,
>$\3, $\4)
>
>
>--- "Charles E. Campbell, Jr." <[hidden email]> wrote:
>
>  
>
>>KWrzalik wrote:
>>
>>    
>>
>>>Hello All.
>>>
>>>I'm rewriting lots of Visual Basic for Applications functions to PHP.
>>>First of all I wanted to add dollar signs in front of variables in
>>>parameter lists. Something like: "Function Foo(a, b, c)" to "Function
>>>Foo($a, $b, $c)". ...snip...
>>>
>>So long as the arguments are on the same line as "Function ...(", the
>>following should do the trick:
>>
>>  :g/Function \h\w*\s*(/s/[(,]\s*\zs\(\h\w*\)/$\1/g
>>
>>    
>>

Hello!

Justin R's solution requires at least three arguments and puts that "$"
in front of just the first  three arguments for each function call.

Mine should work for any number of arguments.  OP's choice!

As currently written, both solutions require all arguments  and the
Function keyword to be on the same line.

Regards,
Chip Campbell


Reply | Threaded
Open this post in threaded view
|

Re: Regexp question.

Tim Chase-2
> As currently written, both solutions require all arguments
> and the Function keyword to be on the same line.

If you need a multi-line version, it will take a bit more chicanary.

Most likely, if VBA is like VB, each continued line has a
trailing underscore, of the form

        Function Foo(longItemOne, itemTwo, _
                itemThree, itemFour)

Since these will choke PHP, you could normalize the whole thing
to one-liners and then apply the previous Dr. Chip or Justin's
solution:

%s/\(\%(Sub\|Function\)\s*[^(]*\s*(\)\(\_[^)]*\))/\=submatch(1).substitute(submatch(2),
'_\r\s*', '', 'g').')'

If you want to handle both Functions and Subs that are both
Public and Private,

%s/^\(\%(Public \|Private
\)\=\%(Sub\|Function\)\s*[^(]*\s*(\)\(\_[^)]*\))/\=submatch(1).substitute(submatch(2),
'_\r\s*', '', 'g').')'

(this also handles public/private and both functions and subs)

They're ugly, but they should normalize all your functions.

As you'll likely need to normalize *all* those lines,

        :%s/_\_$\_s*

should do the trick.

-tim






Reply | Threaded
Open this post in threaded view
|

Re: Regexp question.

Justin Randall-2
In reply to this post by Charles E Campbell Jr
Yes this is true, I was assuming that he needed a Regex that replaced $ on Functions with
exactly 3 arguments. I concede to your regexp sir.  It is much more robust.  Could you
explain how \zs \h \W etc. work.  As you can see I only know of white space \s and the
famus \(.*\) to grab stuff.

--- "Charles E. Campbell, Jr." <[hidden email]> wrote:

> Justin Randall wrote:
>
> >:%s/Function\s*\(.*\)\s*(\s*\(.*\)\s*,\s*\(.*\)\s*,\s*\(.*\)\s*)\s*/Function \1( $\2,
> >$\3, $\4)
> >
> >
> >--- "Charles E. Campbell, Jr." <[hidden email]> wrote:
> >
> >  
> >
> >>KWrzalik wrote:
> >>
> >>    
> >>
> >>>Hello All.
> >>>
> >>>I'm rewriting lots of Visual Basic for Applications functions to PHP.
> >>>First of all I wanted to add dollar signs in front of variables in
> >>>parameter lists. Something like: "Function Foo(a, b, c)" to "Function
> >>>Foo($a, $b, $c)". ...snip...
> >>>
> >>So long as the arguments are on the same line as "Function ...(", the
> >>following should do the trick:
> >>
> >>  :g/Function \h\w*\s*(/s/[(,]\s*\zs\(\h\w*\)/$\1/g
> >>
> >>    
> >>
>
> Hello!
>
> Justin R's solution requires at least three arguments and puts that "$"
> in front of just the first  three arguments for each function call.
>
> Mine should work for any number of arguments.  OP's choice!
>
> As currently written, both solutions require all arguments  and the
> Function keyword to be on the same line.
>
> Regards,
> Chip Campbell
>
>
>



       
               
______________________________________________________
Click here to donate to the Hurricane Katrina relief effort.
http://store.yahoo.com/redcross-donate3/
Reply | Threaded
Open this post in threaded view
|

Re: Regexp question.

Justin Randall-2
In reply to this post by Tim Chase-2
yikes!  give this man the prize.  as you can see, regexps can get ugly in a hurry, but
they can also be a lifesaver.

--- Tim Chase <[hidden email]> wrote:

> > As currently written, both solutions require all arguments
> > and the Function keyword to be on the same line.
>
> If you need a multi-line version, it will take a bit more chicanary.
>
> Most likely, if VBA is like VB, each continued line has a
> trailing underscore, of the form
>
> Function Foo(longItemOne, itemTwo, _
> itemThree, itemFour)
>
> Since these will choke PHP, you could normalize the whole thing
> to one-liners and then apply the previous Dr. Chip or Justin's
> solution:
>
> %s/\(\%(Sub\|Function\)\s*[^(]*\s*(\)\(\_[^)]*\))/\=submatch(1).substitute(submatch(2),
>
> '_\r\s*', '', 'g').')'
>
> If you want to handle both Functions and Subs that are both
> Public and Private,
>
> %s/^\(\%(Public \|Private
> \)\=\%(Sub\|Function\)\s*[^(]*\s*(\)\(\_[^)]*\))/\=submatch(1).substitute(submatch(2),
> '_\r\s*', '', 'g').')'
>
> (this also handles public/private and both functions and subs)
>
> They're ugly, but they should normalize all your functions.
>
> As you'll likely need to normalize *all* those lines,
>
> :%s/_\_$\_s*
>
> should do the trick.
>
> -tim
>
>
>
>
>
>
>



       
               
______________________________________________________
Click here to donate to the Hurricane Katrina relief effort.
http://store.yahoo.com/redcross-donate3/
Reply | Threaded
Open this post in threaded view
|

Re: Regexp question.

Charles E Campbell Jr
In reply to this post by Justin Randall-2

DrChip wrote:
 > :g/Function \h\w*\s*(/s/[(,]\s*\zs\(\h\w*\)/$\1/g

Justin Randall wrote:
 >:%s/Function\s*\(.*\)\s*(\s*\(.*\)\s*,\s*\(.*\)\s*,\s*\(.*\)\s*)\s*/Function
\1( $\2,
 >$\3, $\4)

DrChip replied:
 >Justin R's solution requires at least three arguments and puts that "$"
 >in front of just the first  three arguments for each function call.
 >
 >Mine should work for any number of arguments.  OP's choice!

Justin Randall replied:
 >Yes this is true, I was assuming that he needed a Regex that replaced
$ on Functions with
 >exactly 3 arguments. I concede to your regexp sir.  It is much more
robust.  Could you
 >explain how \zs \h \W etc. work.  As you can see I only know of white
space \s and the
 >famous \(.*\) to grab stuff.

Sure!

g/../   only on lines which match the pattern
  Function   Having the word Function (probably should've used
\<Function, BTW)
  \s*        followed by zero to any number of spaces
  \h         followed by a head-of-word character; ie. [a-zA-Z_]
  \w*        followed by any number of word characters; ie. [a-zA-Z_0-9]

Perform a substitute on such lines:

  [(,]                 matches either "(" or ","
      \s*              followed by any number of whitespaces (tabs or
blanks)
         \zs           assume pattern now begins
                       (so "(" or "," isn't part of the pattern, but is
a required leader)
            \(.....\)  record for posterity (well, for the replacement,
anyway)
              \h\w*    a word (header character, word characters)

Replace the pattern with:
  $\1                  a "$" followed by whatever was matched to the \(...\)

Regards,
Chip Campbell          

Reply | Threaded
Open this post in threaded view
|

Re: Regexp question.

Justin Randall-2
very cool!  thanks for the explination.

--- "Charles E. Campbell, Jr." <[hidden email]> wrote:

>
> DrChip wrote:
>  > :g/Function \h\w*\s*(/s/[(,]\s*\zs\(\h\w*\)/$\1/g
>
> Justin Randall wrote:
>  >:%s/Function\s*\(.*\)\s*(\s*\(.*\)\s*,\s*\(.*\)\s*,\s*\(.*\)\s*)\s*/Function
> \1( $\2,
>  >$\3, $\4)
>
> DrChip replied:
>  >Justin R's solution requires at least three arguments and puts that "$"
>  >in front of just the first  three arguments for each function call.
>  >
>  >Mine should work for any number of arguments.  OP's choice!
>
> Justin Randall replied:
>  >Yes this is true, I was assuming that he needed a Regex that replaced
> $ on Functions with
>  >exactly 3 arguments. I concede to your regexp sir.  It is much more
> robust.  Could you
>  >explain how \zs \h \W etc. work.  As you can see I only know of white
> space \s and the
>  >famous \(.*\) to grab stuff.
>
> Sure!
>
> g/../   only on lines which match the pattern
>   Function   Having the word Function (probably should've used
> \<Function, BTW)
>   \s*        followed by zero to any number of spaces
>   \h         followed by a head-of-word character; ie. [a-zA-Z_]
>   \w*        followed by any number of word characters; ie. [a-zA-Z_0-9]
>
> Perform a substitute on such lines:
>
>   [(,]                 matches either "(" or ","
>       \s*              followed by any number of whitespaces (tabs or
> blanks)
>          \zs           assume pattern now begins
>                        (so "(" or "," isn't part of the pattern, but is
> a required leader)
>             \(.....\)  record for posterity (well, for the replacement,
> anyway)
>               \h\w*    a word (header character, word characters)
>
> Replace the pattern with:
>   $\1                  a "$" followed by whatever was matched to the \(...\)
>
> Regards,
> Chip Campbell          
>
>



       
               
______________________________________________________
Click here to donate to the Hurricane Katrina relief effort.
http://store.yahoo.com/redcross-donate3/