Re: Regular Expression Question

2007-01-26 Thread Sean Hubbell

Gene Kwiecinski wrote:

I hope you don't mind a non-vim solution, but I used to run into this
problem all the time when I wanted to match tabbing for debugging/status
messages that would come to the screen.  I just got so sick and tired of
hopping through the code to add a tab here, remove a tab there, etc.,
that I'd just bunch together all the string constants in one place, at
the top.  Eg:

const char
*msg_help[] = {
"usage:  %s [-options] [infile [outfile]]\n",
"\toptions:\n",
"\t\t-h\thelp\n",
"\t\t-l\tlong (detailed) output\n",
(const char *)0
};

const char
dbg_rdferr[] = "%s:  cannot open \"%s\" for reading\n",
dbg_wrferr[] = "%s:  cannot open \"%s\" for writing\n",
...

and have everything even visually aligned in one place.  Would also let
me "reuse" the same strings as needed (eg, "%d" as an input to sscanf(),
"%02X" as a 2-digit output to fprintf(), etc.) without having to wonder
if I mistyped something that would only break when some rarely-used
piece of code would run.

Then, once all your strings are in a row, just look for

\n"[,;]$

and every string with the necessary newline at the end should be
highlighted.  Any string that's *not* highlighted (ie, would be missing
the trailing newline) would, umm, would *not*, stand out.

Granted, that's not a vimmy solution to your problem, but it's a little
habit I got myself into, and for me at least, it made life a little
easier.

Any help?


  


Yes, I'l try it.

Thanks,

Sean


RE: Regular Expression Question

2007-01-26 Thread Gene Kwiecinski
I hope you don't mind a non-vim solution, but I used to run into this
problem all the time when I wanted to match tabbing for debugging/status
messages that would come to the screen.  I just got so sick and tired of
hopping through the code to add a tab here, remove a tab there, etc.,
that I'd just bunch together all the string constants in one place, at
the top.  Eg:

const char
*msg_help[] = {
"usage:  %s [-options] [infile [outfile]]\n",
"\toptions:\n",
"\t\t-h\thelp\n",
"\t\t-l\tlong (detailed) output\n",
(const char *)0
};

const char
dbg_rdferr[] = "%s:  cannot open \"%s\" for reading\n",
dbg_wrferr[] = "%s:  cannot open \"%s\" for writing\n",
...

and have everything even visually aligned in one place.  Would also let
me "reuse" the same strings as needed (eg, "%d" as an input to sscanf(),
"%02X" as a 2-digit output to fprintf(), etc.) without having to wonder
if I mistyped something that would only break when some rarely-used
piece of code would run.

Then, once all your strings are in a row, just look for

\n"[,;]$

and every string with the necessary newline at the end should be
highlighted.  Any string that's *not* highlighted (ie, would be missing
the trailing newline) would, umm, would *not*, stand out.

Granted, that's not a vimmy solution to your problem, but it's a little
habit I got myself into, and for me at least, it made life a little
easier.

Any help?


Re: Regular Expression Question

2007-01-26 Thread Sean Hubbell

Tim Chase wrote:

print ("small string");
print (
  "This is a very long string");

and I need to format it as so:

print ("small string\n");
print (
  "This is a very long string\n");

Ideally, I would like to do this in one command and I would also like 
to understand the regex itself. So, given the above, here is what I 
understand of the regex pattern:


%s/print\s*(\s*"[^"]*\(\\n\)\@print\s*(\s*"   - my phrase to match including zero or more matching 
spaces at the end print, then a literal paren then zero or more 
spaces up until the quote

[^"]*   - then everything that is not a quote (zero or more)


Doing well up through here...


( - The beginning of the group ???
\\n  - literal \n
) - End group 
\@

You've got the understanding right (though those parens are "\(" and 
"\)" with backslashes).  Those four lines in concert assert that a 
literal "\n" doesn't come before the current point. Without the 
grouping, it would only assure that the previous atom (in this case, 
the "n") didn't appear here, so you'd have problems with things like


print("terminal n")

because it sees the terminal "n" so it doesn't do the substitution.  
By grouping them, you assert "and when you get to this point [before 
the closing quote] and there isn't a literal backslash-en here, then 
we match"


In here, you're missing the "\ze" which means "when doing the 
replacement, treat it as though the thing we're substituting ended 
here, even though there's more stuff we're looking for (namely, the 
double-quote that's next)"



" - my ending quote to match in the pattern print ("")


correct


/&  - ???


This is standard substitution...the slash is the break between the 
search and its replacement.  The ampersand is "the whole previous 
match".  In this case, it's slightly tweaked because of the "\ze" that 
we used...the thing we replace goes up through (but not including) the 
second double-quote.  So it drops in everything from "print" through 
the end of the internal string (sans-closing-quote)



\\n  - literal \n


correct...appending the literal \n you want.


/ - delimeter
g- each occurrence on the line

Then we have the spanning multiple lines option:

\_ [^"]*


that's

\_[

not

\_ [

\_ -  match text over multiple lines (Is this like another 
regex engine, like the one sed uses?)


It's a vim thing:

:help /\_

should drop you in the fray.  It prefixes (infixes?)a number of atoms 
that could include whitespace, so for your change, you'd likely want 
to do something like change the \s atoms to \_s to include newlines.


Does this make since? The area I am having difficulty with is /& and 
how the grouping is working.



Hopefully this sheds some light on matters and helps you tweak your 
own regexps in the future.  If you have any questions, feel free to ask.


-tim






Yes, this helps greatly. Thanks again Tim.

Sean


Re: Regular Expression Question

2007-01-26 Thread Tim Chase

print ("small string");
print (
  "This is a very long string");

and I need to format it as so:

print ("small string\n");
print (
  "This is a very long string\n");

Ideally, I would like to do this in one command and I would also like to 
understand the regex itself. So, given the above, here is what I 
understand of the regex pattern:


%s/print\s*(\s*"[^"]*\(\\n\)\@
% - globally

s  - substitute
/  - delimeter
print\s*(\s*"   - my phrase to match including zero or more matching 
spaces at the end print, then a literal paren then zero or more spaces 
up until the quote

[^"]*   - then everything that is not a quote (zero or more)


Doing well up through here...


( - The beginning of the group ???
\\n  - literal \n
) - End group 
\@

You've got the understanding right (though those parens are "\(" 
and "\)" with backslashes).  Those four lines in concert assert 
that a literal "\n" doesn't come before the current point. 
Without the grouping, it would only assure that the previous atom 
(in this case, the "n") didn't appear here, so you'd have 
problems with things like


print("terminal n")

because it sees the terminal "n" so it doesn't do the 
substitution.  By grouping them, you assert "and when you get to 
this point [before the closing quote] and there isn't a literal 
backslash-en here, then we match"


In here, you're missing the "\ze" which means "when doing the 
replacement, treat it as though the thing we're substituting 
ended here, even though there's more stuff we're looking for 
(namely, the double-quote that's next)"



" - my ending quote to match in the pattern print ("")


correct


/&  - ???


This is standard substitution...the slash is the break between 
the search and its replacement.  The ampersand is "the whole 
previous match".  In this case, it's slightly tweaked because of 
the "\ze" that we used...the thing we replace goes up through 
(but not including) the second double-quote.  So it drops in 
everything from "print" through the end of the internal string 
(sans-closing-quote)



\\n  - literal \n


correct...appending the literal \n you want.


/ - delimeter
g- each occurrence on the line

Then we have the spanning multiple lines option:

\_ [^"]*


that's

\_[

not

\_ [

\_ -  match text over multiple lines (Is this like another regex 
engine, like the one sed uses?)


It's a vim thing:

:help /\_

should drop you in the fray.  It prefixes (infixes?)a number of 
atoms that could include whitespace, so for your change, you'd 
likely want to do something like change the \s atoms to \_s to 
include newlines.


Does this make since? The area I am having difficulty with is /& and how 
the grouping is working.



Hopefully this sheds some light on matters and helps you tweak 
your own regexps in the future.  If you have any questions, feel 
free to ask.


-tim





Re: Regular Expression Question

2007-01-26 Thread Sean Hubbell



print("This is 1.\n");print("This is 2.");
print("This is 3.\n");


I would like the above to be formated like (which is just adding in 
the newline a print that may not have it, but only if it does not 
have it):


print("This is 1.\n");print("This is 2.");
print("This is 3.\n");



I presume you mean that second section to read

print("This is 1.\n");print("This is 2.\n");
print("This is 3.\n");

adding in that "\n" after "2."

On the assumption that you don't have quotation-marks escaped in your 
strings such as


print ("She said \"hello\" to me");

you should be able to do something like

%s/print\s*(\s*"[^"]*\(\\n\)\@which should catch most of the non-pathological cases.  If quotes can 
span lines, such as


print ("this is a
really long string")

then you can change

[^"]*

to

\_[^"]*


I just noticed that I also need to support the following as well:

print ("small string");
print (
 "This is a very long string");

and I need to format it as so:

print ("small string\n");
print (
 "This is a very long string\n");

Ideally, I would like to do this in one command and I would also like to 
understand the regex itself. So, given the above, here is what I 
understand of the regex pattern:


   %s/print\s*(\s*"[^"]*\(\\n\)\@   
% - globally

s  - substitute
/  - delimeter
print\s*(\s*"   - my phrase to match including zero or more matching 
spaces at the end print, then a literal paren then zero or more spaces 
up until the quote

[^"]*   - then everything that is not a quote (zero or more)
( - The beginning of the group ???
\\n  - literal \n
) - End group 
\@\_ -  match text over multiple lines (Is this like another regex 
engine, like the one sed uses?)

[^"]*- everything but a quote (zero or more)


Does this make since? The area I am having difficulty with is /& and how 
the grouping is working.


Thanks in advance,

Sean


Re: Regular Expression Question

2007-01-25 Thread Sean Hubbell

Tim Chase wrote:

print("This is 1.\n");print("This is 2.");
print("This is 3.\n");


I would like the above to be formated like (which is just adding in 
the newline a print that may not have it, but only if it does not 
have it):


print("This is 1.\n");print("This is 2.");
print("This is 3.\n");



I presume you mean that second section to read

print("This is 1.\n");print("This is 2.\n");
print("This is 3.\n");

adding in that "\n" after "2."

On the assumption that you don't have quotation-marks escaped in your 
strings such as


print ("She said \"hello\" to me");

you should be able to do something like

%s/print\s*(\s*"[^"]*\(\\n\)\@which should catch most of the non-pathological cases.  If quotes can 
span lines, such as


print ("this is a
really long string")

then you can change

[^"]*

to

\_[^"]*


HTH,

-tim





Thanks Tim.

Sean


Re: Regular Expression Question

2007-01-25 Thread Tim Chase

print("This is 1.\n");print("This is 2.");
print("This is 3.\n");


I would like the above to be formated like (which is just adding in the 
newline a print that may not have it, but only if it does not have it):


print("This is 1.\n");print("This is 2.");
print("This is 3.\n");



I presume you mean that second section to read

print("This is 1.\n");print("This is 2.\n");
print("This is 3.\n");

adding in that "\n" after "2."

On the assumption that you don't have quotation-marks escaped in 
your strings such as


print ("She said \"hello\" to me");

you should be able to do something like

%s/print\s*(\s*"[^"]*\(\\n\)\@which should catch most of the non-pathological cases.  If quotes 
can span lines, such as


print ("this is a
really long string")

then you can change

[^"]*

to

\_[^"]*


HTH,

-tim