Dear All

I couldn't let this problem go while I didn't understand it. I think I got an 
alternative solution using \zs, which is faster and is recommended by VIM's 
documentation.

:%s/\("[^"]*"\)*\zs[^"]*/\L&/gc

It seems to work and is based on the principles that Tim laid down. Anyone 
agree?

Best
Felipe




On 28/07/2010, at 9:29 PM, Tim Chase wrote:

> 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