Friday, July 30, 2010

Re: Replace except enclosed by delimiters (")

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

No comments: