vim: How to search for a hard-coded string (not regex)? - vim

In order to search for a string in Vim, I click "/" and then type the word that I have to search. Vim looks at this string as regular expression. I want to know how to search a string, as it it, and not treat it as a regex.

Search commands always search for patterns (also known as regular expressions). You can make patterns more or less magic but cannot turn metacharacters completely off. If you have a fixed string you have to escape the characters that vim understands as metacharacters.

With the very nomagic mode of Vim's regular expressions (:help /\V), only the backslash is a special character that needs escaping.
So, prepend \V to your literal search, and (either manually or via escape(pattern, '\')) duplicate any backslashes. The following turns a "regular" search in to a literal one; you could define a mapping for that:
:let #/ = '\V' . escape(#/, '\')

Related

How can I find “<html>“ in the Vim buffer?

I want to search a HTML tag in my html file using Vim.
I tried \<html\> but it means search only the “html” word.
I don’t know how to find the greater or lower characters.
Vim has 4 modes of regular expression interpretation:
very no magic,
no magic,
magic and
very magic.
The default is magic (check with :set magic?), which can be a bit surprising because some non alphanumeric characters have special regex meanings but not all. In particular ^$*. do but most other characters do not. For example to match alternatives you'd have to escape the pipe character this\|that and this|that would match the literal string "this|that".
In your case, < does not have a special meaning but \< does (beginning of a word). Searching for <html> will work, but when in doubt you can activate "very no magic" mode by prepending your search with \V (so /\V<html>) where every character matches the character itself. If and when you want to activate all regex features, you can activate "very magic" mode with lowercase \v (hence /\v<html> will search for the word "html").
In Normal mode, the / command searches forward (? — backward). Suppose we are at the top, and want to search forward. So, if we want to find a particular tag, like “div” for example, we should type the following:
/\V<div>
Here \V turns on the ”very unmagic” mode in which a symbol has no any special meaning unless it is preceded by a backslash. (I use only the “very magic” and “very unmagic” modes and don’t use the “magic” and “unmagic” modes.)
If we want to find any html tag, i.e. something between angle brackets, we may type one of the following:
/\V<\[^<>]\+>
/\v\<[^<>]+\>
That will find and highlight all the tags including their attributes.
You may create a convenient keymap for the mode you prefer, for example:
nnoremap // /\V
Now, double hitting of / brings you to the search line with “very unmagic” mode.
Type :help pattern for more information.

vi replaces with empty when searching

In vi (from cygwin), when I do searching:
:%s/something
It just replaces the something with empty string like
:%s/something// .
I've googled for a while but nothing really mentions this. Is there anything I should add to the .vimrc or .exrc to make this work?
Thanks!
In vi and vim, when you search for a pattern, you can search it again by simply typing /. It is understood that the previous pattern has to be used when no pattern is specified for searching.
(Though, you can press n for finding next occurence)
Same way, when you give a source (pattern) and leave the replacement in substitute command, it assumes that the replacement is empty and hence the given pattern is replaced with no characters (in other words, the pattern is removed)
In your case, you should understand that % stand for whole file(buffer) and s for substitute. To search, you can simply use /, followed by a pattern. To substitute , you will use :s. You need not confuse searching and substituting. Hence, no need for such settings in ~/.exrc. Also, remember that / is enough to search the whole buffer and % isnt necessary with /. / searches the entire buffer implicitly.
You may also want to look at :g/Pattern/. Learn more about it by searching :help global or :help :g in command line.
The format of a substitution in vim is as follows:
:[range]s[ubstitute]/{pattern}/{string}/[flags] [count]
In your case you have omitted the string from the substitution command and here what vim documentation stated about it:
If the {string} is omitted the substitute is done as if it's empty.
Thus the matched pattern is deleted. The separator after {pattern}
can also be left out then. Example: >
:%s/TESTING This deletes "TESTING" from all lines, but only one per line.
For compatibility with Vi these two exceptions are allowed:
"/{string}/" and "\?{string}?" do the same as "//{string}/r".
"\&{string}&" does the same as "//{string}/".
E146
Instead of the '/' which surrounds the pattern and replacement string, 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. Example: >
:s+/+//+
In other words :%s/something and :%s;something or :%s,something have all the same behavior because the / ; and , in the last examples are considered only as SIMPLE SEPARATOR

How to match using regular expression in matchstr function of vim script?

I'm trying to understand how VIM uses 'pattern' argument to 'matchstr' function.
I tried creating a pattern that matches either 'a' or 'b' but I'm unable to do this.
Here is what I tried:
:echo matchstr("ab", "a|b")
:echo matchstr("ab", "a\|b")
:echo matchstr("ab", "(a|b)")
:echo matchstr("ab", "(a|b)")
:echo matchstr("ab", "(a\|b)")
Note: 'set magic?' shows 'magic'
Vim uses a regex dialect, in which by default you need to escape special letters, if you need their regex feature. E.g. for OR you need to write \| and not like in perl regexes | This applies e.g. to the multi atom + and the OR atom |. (This can be changed by the regex atom \v which provides a more perl like regex dialect, see :h /\v)
Now you are using double quotes in your expression. When using double quotes, Vim will parse special characters and therefore remove one backslash, before the regex engine even sees them. Therefore, you need to either double your backslashes or use single quotes. This is explained at :h expr-quote

How to search for a string containing a regex in Vim?

Is it possible to search a string that is a regex, without escaping all the fancy characters?
For example, I want to find this string in my source file: ^[\d\| *]$, without escaping \, $, etc.
I would like to just copy and paste the regex and get the result.
What you want is a grep that searches for matching strings, rather than attempting to match a regular expression. With GNU grep, you can invoke the command with the
-F or --fixed-strings flags, or just invoke the command as fgrep instead. The following are all equivalent:
grep -F '^[\d\| *]$'
grep --fixed-strings '^[\d\| *]$'
fgrep '^[\d\| *]$'
Fixed-string searches are exactly what you need when you want to match code that represents a regular expression, or when you want a faster grep that doesn't need the advanced matching capability of a regular expression engine.
There is an easy way to avoid special treatment of the characters
in Vim regular expressions. The \V specifier allows to switch
interpretation of the rest of the pattern to the “very nomagic” mode,
which means that every character but the backslash is understood
literally.
Therefore, one can set the last search register accordingly:
:let #/ = '\V' . escape('^[\d\| *]$', '\')
and use n and N for searching immediately.
You can use the command line tool fgrep (“fast grep”),
Supposing you have yanked the regexp to search for to the default register (#"), you can do this:
/\V<C-R><C-R>=escape(#", '/\')<CR><CR>
The \V starts a "very nomagic" search, where only atoms starting with a backslash have special, non-literal meaning. The escape() renders all those contained backslashes ineffective (and escapes / which would otherwise end the search pattern), so that this is a purely literal search. The text is inserted via Ctrl+R= into the search command line.

vim regexps from the perl's point of view: which special characters to escape with backslash

Imagine, we have to construct a regexp in vi/vim. Which special characters we have to escape with backslash?
By special characters I mean the following chars: {}|()-[]+*.^$?
Seems like we have to escape: {|()+?
And leave as is: }^$*.[]-
Thanks.
p.s. AFAIK, we have no '?' character in vi/vim but '=' instead which should be also escaped by backslash.
I think the Vim documentation on magic characters will give you a definitive list.
In vim:
:help magic
I think the simplest way, that will work regardless of vim's magic setting, is
let re = '\V' . escape(fixed_string, '\')
\V disables magic entirely from that point onward in the RE. This means that anything not preceded by a single backslash (well, technically by an odd number of backslashes) is a normal character. Since we escape any backslashes in the fixed string, there can be no magic characters contained in it.
Remember that with \V in effect, you have to backslash-prefix any RE meta-characters. So if you're looking for a line that entirely consists of the fixed string, you would
let full_line_re = '\V\^' . escape(fixed_string, '\') . '\$'
Also keep in mind that vim's ignorecase and smartcase settings will affect RE behaviour. The \C (case-sensitive) and \c (case-insensitive) switches work the same way as \V: they will override those settings for the part of any regexp which follows them.

Resources