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

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.

Related

disable SublimeREPL backslash highlights

When running SublimeRepl with python, I have noticed that it always highlights some backslash + characters. I am not sure why this, any suggestion into why this is going on and how to disable this ?
side note
My search led me to ANSII escape code/color code, or even syntax highlighting. are these relevant ? I am not sure since I don't know much about these topics
In python unless an 'r' or 'R' prefix is present, every character after '\' is interpreted as an escape sequence.And the ones that are highlighted here are not valid escape sequences. \a is not highlighted here in the same fashion because it is a valid escape sequence.
\a ASCII Bell (BEL)
If you want to use a backslash inside a string, you should use double slashes(\\) like this,
>>> print("c:\\my_main\\asdf\\xsdf")

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

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(#/, '\')

Vim Search/replace: what do I need to escape?

I'm trying to search and replace $data['user'] for $data['sessionUser'].
However, no matter what search string I use, I always get a "pattern not found" as the result of it.
So, what would be the correct search string? Do I need to escape any of these characters?
:%s/$data['user']/$data['sessionUser']/g
:%s/\$data\[\'user\'\]/$data['sessionUser']/g
I did not test this, but I guess it should work.
Here's a list of all special search characters you need to escape in Vim: `^$.*[~)+/
There's nothing wrong with with the answers given, but you can do this:
:%s/$data\['\zsuser\ze']/sessionUser/g
\zs and \ze can be used to delimit the part of the match that is affected by the replacement.
You don't need to escape the $ since it's the at the start of the pattern and can't match an EOL here. And you don't need to escape the ] since it doesn't have a matching starting [. However there's certainly no harm in escaping these characters if you can't remember all the rules. See :help pattern.txt for the full details, but don't try to digest it all in one go!
If you want to get fancy, you can do:
:%s/$data\['\zsuser\ze']/session\u&/g
& refers to the entire matched text (delimited by \zs and \ze if present), so it becomes 'user' in this case. The \u when used in a replacement string makes the next character upper-case. I hope this helps.
Search and replace in vim is almost identical to sed, so use the same escapes as you would with that:
:%s/\$data\['user'\]/$data['session']/g
Note that you only really need to escape special characters in the search part (the part between the first set of //s). The only character you need to escape in the replace part is the escape character \ itself (which you're not using here).
The [ char has a meaning in regex. It stands for character ranges. The $ char has a meaning too. It stands for end-line anchor. So you have to escape a lot of things. I suggest you to try a little plugin like this or this one and use a visual search.

Exact string match in vim? (Like 'regex-off' mode in less.)

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

Can you write unescaped search terms in the Vim command line?

When I do a search and replace on a yanked line that has characters that require escaping it's really annoying to have to go back through the command line string and escape all the special characters.
Is there a way to use a literal (raw) string modifer like in python: str = r'\unescaped\'?
Use the \V modifier:
:%s/\V$foo//g
See also :help /magic
I just thought of doing this instead: :%s;\foo\;bar;g. This solves the escape the backslash problem Manni points out.

Resources