Saturday, January 29, 2011

Re: How to replace "\" to "\\"

Am 27.01.2011 03:51, schrieb Wayne Young:
> Hi Andy,
>
> I can understand the pattern ifys0325 gave now (thanks ifys0325!) ,
> but yours really scared me... All I can know is the last one with a
> "\=". The first one seems to be: find a "\\*", without a "\" ahead,
> and without a "\\" followed?
> And the second one: no "\" leads, but followed by a "\", and it
> matches "\\*" ?
>
> I think I may wrong to parse those two, but I am not able to
> understand them at all...
>
> On Thu, Jan 27, 2011 at 5:03 AM, Andy Wokula<anwoku@yahoo.de> wrote:
>
>> Am 26.01.2011 07:34, schrieb Wayne Young:
>>
>> Thanks very much. The second works!
>>> I am still wondering how it work. It seems to replace the "
>>> \%(\\\)\@<!\\\$(\\\)\@! " part to "\\\\". Would you help to explain
>>> the meaning of the replaced part?
>>
>> What about '\\\', the given substitute will not turn it into '\\\\'.

With spaces to make it readable:

First command:

:%s/ \\ \@<! \%( \\ \\ \) * \\ \\ \@! / \\ & / g

works as follows.
Find an odd number of backslashes (one or more):

\%( \\ \\ \) * \\

The above will find '\\\' at the start of '\\\\' (which is bad); make
sure no '\' follows the match:

\%( \\ \\ \) * \\ \\ \@!

Now the above will find '\\\' at the end of '\\\\' (after backtracking,
the next try starts one position to the right); make sure no '\'
precedes the match:

\\ \@<! \%( \\ \\ \) * \\ \\ \@!

Eventually, '\','\\\',... are found and '\\','\\\\',... are skipped.

The replace part is: a backslash plus the whole matched text.


Second command:

:%s/ \\ \@<! \%( \%( \\ \\ \) * \) \@> \\ / \\ & / g

This one makes use of \@> (rarely to be found in patterns).

Find an odd number of '\':

\%( \%( \\ \\ \) * \) \@> \\

The above will find '\\\', but not at the start of '\\\\', because
'\\\\' is matched by \%( \\ \\ \) * and the surrounding \@> disables
backtracking (which would allow a match for the following \\ ).

Now when the whole pattern (so far) fails, the next try starts one
position to the right, allowing a match for '\\\' at the end of '\\\\'.
Like with the first command, this is avoided with \\ \@<! .


Third command:

:%s/ \\ \\ \= / \\ \\ / g

This one processes each encountered backslash, no problem with
backtracking then.


Get help:

:h pattern
:h /\@!

:h sub-replace-special

etc.

--
Andy

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