On Tue, Mar 31, 2009 at 4:40 PM, A. S. Budden <[email protected]> wrote:

>
> 2009/3/31 ivan budiselic <[email protected]>:
> > On Tue, Mar 31, 2009 at 10:13 AM, Andreas Bernauer <[email protected]>
> > wrote:
> >>
> >> ivan budiselic wrote:
> >> >>> So, for the line:
> >> >>>
> >> >>> 1234 a a "a" a
> >> >>>
> >> >>> I'd like to get:
> >> >>>
> >> >>> 1234 b b "a" b
> >> >>>
> >> >>> The question is, is this possible and how.
> >> >>>
> >> >>> What I've tried is
> >> >>> let line = substitute(line, '\([^\"]\{-}\)a', "\\1b", "g")
> >> >>
> >> >> ...because \{-} matches also 0 times; what you wanted is \{-1,}:
> >> >>
> >> >> let line = substitute('123 a "a" a', '\([^"]\{-1,}\)a', '\1b', 'g')
> >> >>
> >> >
> >> > Ok, this worked pretty well, except that it doesn't work for cases
> when
> >> > there's an 'a' at the start of the line (which I might be able to
> fix),
> >> > and
> >>
> >> Allow matching 'start-of-line' (^) in front of 'a', too; see below.
> >>
> >> > the other problem which I wasn't specific enough about, and that is
> that
> >> > I'd
> >> > like the change to happen to 'a's outside of strings, so for example
> >> > "xxxaxxx" shouldn't match. I guess this changes things quite a bit,
> >> > sorry
> >> > for not being clear enough.
> >>
> >> So, would you like further help? If yes, could you provide an example
> for
> >> what
> >> you want to achieve?
> >>
> >> s/\(^\|\s\)\zsa\ze\s\?/b/
> >> works for
> >> a 123 a a "xxxxaxxx" a
> >> ==>
> >> b 123 b b "xxxxaxxx" b
> >
> > Ok, so a complete example would be this:
> >
> > a 123 a "xy a xax xa a" xa ax xax "a" " a " " xa ax xax " a
> >
> > should result in
> >
> > b 123 b "xy a xax xa a" xb bx xbx "a" " a " " xa ax axa " b
> >
> > In words, all occurrences of 'a' outside of double quotes change to b,
> and
> > all occurrences of 'a' inside double qoutes stay uncanged.
> >
> > The line you suggested doesn't handle the quotes. What I tried now is:
> >
> > let line = substitute(line, '^\%([^"]\|.\{-}".\{-}".\{-}\)\{-}\zsa\ze',
> 'b',
> > 'g')
> >
> > Now, the problem I'm having is that I'm obviously missunderstanding the
> 'g'
> > flag. This line does what I want, but only does the substitution for the
> > first 'a' (so I can solve the problem by running it multiple times, until
> a
> > match is possible, which is what I thought the 'g' flag is supposed to
> do).
> [snip]
>
> The 'g' flag will perform as many substitutions as match on the line
> in a single attempt.  Therefore, it will only match once if the
> pattern contains '^' as it will match at the start of the line.  If
> you consider the effect of how you expect it to work, given a string:
>
> bbbabab
>
> If you did s/a/aa/g and it kept trying until it couldn't match, the
> first attempt would make
>
> bbbaabab
>
> the second:
>
> bbbaaabab
>
> and so on until the computer gives up in an infinite-loop induced
> panic.  Therefore, if you can imagine that the list of matches is
> found (in this case character 4 and 6) and THEN each instance is
> replaced, giving bbbaabaab.
>
> I'm not sure of a good regular expression to do what you want, but it
> might be simplest to use a construct like:
>
> while match(line, regexp) != -1
>    let line = substitute(line, regexp, subpattern, '')
> endwhile
>
> Just make sure that the result of the substitution can never create a
> situation in which the regexp will match, or you'll be in an infinite
> loop again.
>

That's what I'll probably end up doing. Thanks.

Ivan

--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_use" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---

Reply via email to