Loading ...
Sorry, an error occurred while loading the content.

Re: Regex substitute only outside "strings"

Expand Messages
  • ivan budiselic
    ... That s what I ll probably end up doing. Thanks. Ivan --~--~---------~--~----~------------~-------~--~----~ You received this message from the vim_use
    Message 1 of 8 , Mar 31, 2009
    • 0 Attachment
      On Tue, Mar 31, 2009 at 4:40 PM, A. S. Budden <abudden@...> wrote:

      2009/3/31 ivan budiselic <ibudiselic@...>:
      > On Tue, Mar 31, 2009 at 10:13 AM, Andreas Bernauer <vim-dev-1@...>
      > 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).

      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:


      If you did s/a/aa/g and it kept trying until it couldn't match, the
      first attempt would make


      the second:


      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, '')

      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.


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

    Your message has been successfully submitted and would be delivered to recipients shortly.