On 07/27/10 22:43, fd wrote:
Well, I'm starting to use Vim and still getting the hang of it. I have
a problem where I need to replace a text to lowercase, except if the
text is enclosed by double quotes and I'm not quite getting it.

As an example give the input text

FOO, FOO, fooO, "foOO"

I want it to become

foo, foo, fooo, "foOO"

If you're just getting started with Vim, this is a rather tricky problem. However, you've come to the right mailing list. :)

You can use the following:

:%s/\%(^\%([^"]\+\|"[^"]*"\)*\)\@<=[^"]\+/\L&/g

which roughly translates as

 \%(...\)\@<=     assert that there are an even (including 0)
                  number of quote-marks before this text
 [^"]\+           one or more non-quote characters comprising
                  the actual match (the stuff we'll lower-case)

replaced with

 \L&              the lowercase version of the match

The tricky part is the assertion:

 ^                looking back to the beginning of the line
 \(...\|...\)*    you can have one of these two things
                    zero or more times (the "*"):
 [^"]             either characters that aren't quotes (on
                    the left side of the "\|"; or (on the
                    right-side of the "\|")
 "                an opening quote
 [^"]             followed by stuff that isn't a quote
 "                followed by a closing quote

The assertion is then made with the "\@<=" which requires that vim look backwards (even before the match's start) to ensure this condition is met.

The only place it would break is if you expect to have embedded newlines crossing quotes:

  ABC, DEF, "GH
IJK", LMN, OPQ

being treated as one line. But if you do that, you get what you deserve for having such pathological input ;-) Though if you have this case, I'd use the "decorate, transform, undecorate" pattern: (1) join lines with odd numbers of quotes until you don't have any more, joining with some unused character; (2) then perform the above transformation; (3) then replace all my placeholder characters with new-lines to get the line-breaks restored. Then (4) I'd go smack the head of the person who created the file-format that allowed line-breaks in quoted text ;-)

-tim







--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

Reply via email to