Replace ‘&’ not at end of line and not preceded by ‘\’ with ‘\&’ in Vim
I need to replace &
with \&
when &
is not at the end of the line and it is not preced开发者_如何学编程ed by \
. I can successfully find &
when it is not preceded by \
, but I can not exclude those that are at the end of the line.
line 1 &
line 2
line 3 another &
line 4 & is at the middle
In above four lines, I only want to replace &
with \&
at line 4.
How could I do that?
Here is what I can do so far:
/\(\\\)\@<!&
Find &
when it is not preceded by \
. By adding negative lookahead \@!$
, that is using:
/\(\\\)\@<!&\@!$
I should get those &
that are not at the end of the line, but I can not.
The reason why the command listed in the question statement does not
work as its author expects, is that the \@!
atom is used incorrectly.
This atom matches (with zero width) if the preceding, not the
following atom does not match (see :help /\@!
).
Thus, the revised substitution command should be
:%s/\\\@<!&\_$\@!/\\\&/g
The \_$
atom is used to match end of line instead of the $
one,
since the latter can be used for this purpose only at the end of
pattern or just before \|
, \)
, or \n
atoms (see :help /$
and :help /\_$
).
However, there is a simpler way of performing the substitution following the same rules. Rather than matching an ampersand not followed by end of line, one can simply match an ampersand followed by any non-newline character, instead:
:%s/\\\@<!&./\\&/g
Contrary to the first command, &
and not \&
is used in the
replacement string, so that not only a single ampersand character
would be inserted, but the whole matched text, which now includes
the character following the ampersand in the match (see :help s/\&
).
About something like this?
:%s/\(.\|^\)&\(.\)/\1\\\&\2/g
Basically, replace any &
if it's in the beginning of the line, or preceded by any character, and followed by any character.
精彩评论