Exact string match in vim? (Like 'regex-off' mode in less.)
Solution 1
Looking at your specific example, probably the easiest way to do this (since \V won't help here) is to use ?
instead of /
: then you won't have to escape the /
s:
?((N/N)/(N/N))/N
This will search backwards instead of forwards, but you can always do 'N' instead of 'n' to search forwards after the first go. Or you can press /
followed by the up cursor key to automatically escape the forward slashes.
However, there's nothing you can easily do about escaping backslashes. I guess you could do:
:let @/ = escape(pattern, '\')
and then use n
to search, but it's probably not much easier. The best I can come up with is:
:command! -nargs=1 S let @/ = escape('<args>', '\')
Then do:
:S (N)/(N+1)\(N)
n
Solution 2
Depending on the exact string you're searching, the \V
prefix will probably do the trick.
See :help \V
:
after: \v \m \M \V matches ~
'magic' 'nomagic'
$ $ $ \$ matches end-of-line
. . \. \. matches any character
* * \* \* any number of the previous atom
() \(\) \(\) \(\) grouping into an atom
| \| \| \| separating alternatives
\a \a \a \a alphabetic character
\\ \\ \\ \\ literal backslash
\. \. . . literal dot
\{ { { { literal '{'
a a a a literal 'a'
So if I have a string hello.*$world
, I can use the command /\V.*$
to find just .*$
-- the only part of the string that should need escaping is another backslash, but you can still do grouping, etc., by escaping the special symbol.
Another command you can use to "avoid" forward slashes is:
:g #\V((N/N)/(N/N))/N#
The :g
command is a global search, noting that:
:[range]g[lobal]/{pattern}/[cmd]
Execute the Ex command [cmd] (default ":p") on the
lines within [range] where {pattern} matches.
Instead of the '/' which surrounds the {pattern}, you can use any other
single byte character, but not an alphanumeric character, '\', '"' or '|'.
This is useful if you want to include a '/' in the search pattern or
replacement string.
So where I used a #
, you could use a ?
, @
, or whatever other character meeting the above condition. The catch with that :g
command is that it expects a command at the end, so if you do not have a trailing space after the final character, it won't perform the search as you would expect. And again, even though you're using \V
, you'll still have to escape backslashes.
If that still doesn't cut it for you, this Nabble post has a suggestion that takes a literal string with embedded backslashes and other special Vim characters, and claims to search for it without a problem; but it requires creating a Vim function, which may or may not be okay in your environment.
Solution 3
Maybe something like this:
nmap <Leader>s :execute '/\V' . escape(input('/'), '\\/')<CR>
It'll give you a /
prompt and behave otherwise like the built-in search, but it won't do search-as-you-type or other such goodies.

jogloran
I am a computational linguistics PhD candidate. But before that, long before that, I fell in love with languages. By the way, if you're addicted to Stack Exchange and use iOS, check out Stackwise for iOS and browse Stack Exchange beautifully.
Updated on July 09, 2022Comments
-
jogloran 7 months
In vim, I often want to search on a string with finicky characters which need escaping. Is there a way I can turn off the meaning of all special characters, kind of like regex-off mode in less, or fgrep?
I am dealing with particularly hairy strings; here's an example:
((N/N)/(N/N))/N
Not having to escape any characters to do a search in vim would be a major timesaver.
\V in Vim helps with some metacharacters, but critically not / or \.
Thanks all! In the end, I added this to my .vimrc:command! -nargs=1 S let @/ = escape('<args>', '\') nmap <Leader>S :execute(":S " . input('Regex-off: /'))<CR>
-
jogloran over 13 yearsThanks Mark! But I'm trying to match strings which are probably purpose-built to frustrate vim's escaping. I've edited the question with an example. Are you aware of any way to get rid of the meaning of all special metacharacters, including \ and /, just like /usr/bin/less with no-regex (Ctrl+R) does?
-
jogloran over 13 yearsGreat answers, but escaping the input is probably the closest I'll get to No-regex. No search as you type, but then again neither does 'less'!
-
Aaron Thoma almost 8 years(This uses
:/
, which works line-based, so it puts the cursor at the beginning of the match's line; (as opposed to/
, which jumps to the match's position within its line.)) -
Aaron Thoma almost 8 yearsThe second
\
inescape(…, '\\/')
is redundant, becauseescape()
's second parameter is a list of characters, and single quotes denote a'…'
literal string where no escape sequences are interpreted. (I suggest writing'/\'
to make it visually apparent that the\
does not escape the/
.) -
teadotjay over 5 years:g#((N/N)/(N/N))/N##! works for your example. For search-as-you-type, ?((N/N)/(N/N))/N also works, but searches backwards.