Re: Regular Expression Question
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
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
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
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
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
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
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