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 -~----------~----~----~----~------~----~------~--~---
