In vim is it possible to use the same regex escaping rules for :substitute and search? - regex

If I do a search (with magic) like: /\v\$[^ ]+\$ I get matches in my file, however if I substitute with the same search pattern: :%smagic/\$[^ ]+\$//, I need to escape the +.
Is it possible to make the escaping behave in the same way for magic search and magic substitute?

:smagic is like :s with 'magic' on, which is the default (and should not be changes for plugin portability, as its :help notes). The \v special atom specifies very magic, so additional atoms (like \+) do not need the preceding backslash.
There's no corresponding :s command variant, but why don't you just keep the \v in the pattern:
:%s/\v\$[^ ]+\$//
(Also, if you've previously searched for that, you can leave off the pattern completely: :%s///.)

use \v instead of magic
:%s/\v\$[^ ]+\$//

Related

Search string enclosed in quotes in Vim

In vim I need to search all strings in quotes e.g. 'foo'
Does one see the problem in this regex? E486: Pattern not found \'([^']*)'
:\/'([^']*)'
Regex Tester
First problem is that your use of find is a bit confusing. If you want
to just find, use /. The colon is not necessary (which indicates
command mode). If you're using the find as a range (basically the same
thing, / is just an empty command with a range) you can use the colon,
but either way escaping the first slash is not necessary.
The other main problem is that parenthesis by default need to be escaped
if you meant a capturing group. All of this is dependant on your
'magic' option reading the help for the /magic topic (you can do a
:h magic) is highly recommended. With "vanilla" Vim settings, the
regex you need looks live this:
/'\([^']*\)'
With very magic enable (by using the \v atom) this can be simplified
to your original design:
/\v'([^']*)'
Alternatively you can use
\v'(\a+)'
this regex performs similar than yours, except when nested quotes are encountered. In the text:
The user's first 'answer'.
The regex \v'(\a+)' will capture answer while your original regex (corrected by sidyll) \v'([^']*)' will capture 's first '.

Basic Vim - Search and Replace text bounded by specific characters

Say I wanted to replace :
"Christoph Waltz" = "That's a Bingo";
"Gary Coleman" = "What are you talking about, dear Willis?";
to just have :
"Christoph Waltz"
"Gary Coleman"
i.e. I want to remove all the characters including and after the = and the ;
I thought the regex for finding the pattern would be \=.*?\;. In vim, I tried :
:%s/\=.*?\;$//g
but it gave me an Invalid Command error and Nothing after \=. How do I remove the above text? Apologies, but I'm new to this.
Vim's regular expression dialect is different; its escaping is optimized for text searches. See :help perl-patterns for a comparison with Perl regular expressions. As #EvergreenTree has noted, you can influence the escaping behavior with special atoms; cp. :help /\v.
For your example, the non-greedy match is .\{-}, not .*?, and, as mentioned, you mustn't escape several literal characters:
:%s/ =.\{-};$//
(The /g flag is superfluous, too; there can be only one match anchored to the end via $.)
This is because of vim's weird handling of regexes by default. Instead of \= interpreting as a literal =, it interprets it as a special regex character. To make vim's regex system work more normally, you can prefix it with \v, which is "very magic" mode. This should do the trick:
%s/\v\=.*\;$//g
I won't explain how vim enterprets every single character in very magic mode here, but you can read about it in this help topic:
:help /magic

Vim regex to substitute/escape pipe characters

Let's suppose I have a line:
a|b|c
I'd like to run a regex to convert it to:
a\|b\|c
In most regex engines I'm familiar with, something like s%\|%\\|%g should work. If I try this in Vim, I get:
\|a\||\|b\||\|c
As it turns out, I discovered the answer while typing up this question. I'll submit it with my solution, anyway, as I was a bit surprised a search didn't turn up any duplicates.
vim has its own regex syntax. There is a comparison with PCRE in vim help doc (see :help perl-patterns).
except for that, vim has no magic/magic/very magic mode. :h magic to check the table.
by default, vim has magic mode. if you want to make the :s command in your question work, just active the very magic:
:s/\v\|/\\|/g
Vim does the opposite of PCRE in this regard: | is a literal pipe character, with \| serving as the alternation operator. I couldn't find an appropriate escape sequence because the pipe character does not need to be escaped.
The following command works for the line in my example:
:. s%|%\\|%g
If you use very-magic (use \v) you'll have the Perl/pcre behaviour on most special characters (excl. the vim specifics):
:s#\v\|#\\|#g

Perform a non-regex search/replace in vim

When doing search/replace in vim, I almost never need to use regex, so it's a pain to constantly be escaping everything, Is there a way to make it default to not using regex or is there an alternative command to accomplish this?
As an example, if I want to replace < with <, I'd like to just be able to type s/</</g instead of s/\</\&lt\;/g
For the :s command there is a shortcut to disable or force magic. To turn off magic use :sno like:
:sno/search_string/replace_string/g
Found here: http://vim.wikia.com/wiki/Simplifying_regular_expressions_using_magic_and_no-magic
Use this option:
set nomagic
See :help /magic
The problem is primarily caused by confusion about the role of the & in the replacement string. The replacement string is not a reg-ex, although it has some special characters, like &. You can read about role of & in replacement string here: :h sub-replace-special .
I suspect the main problem for OP is not necessarily typing the extra backslashes, but rather remembering when a backslash is needed and when not. One workaround may be to start making use of "replacement expressions" when unsure. ( See :h sub-replace-expression.) This requires putting a `\=' in replacement string but for some people it may give you more natural control over what's being substituted, since putting a string literal in single quotes will give you the replacement string you want. For example, this substitute does what OP wants:
:s/</\='<'/g
If you want to search literally, you can use the \V regex atom. This almost does what you want, except that you also need to escape the backslash. You could define your own search command, that would search literally. Something like this:
:com! -nargs=1 Search :let #/='\V'.escape(<q-args>, '\/')| normal! n
And then use :Search /foobar/baz
For Substitute, you could then after a :Search command simply use
:%s//replace/g
since then Vim would implicitly pick up the last search item and use the for replacing.
(Just want to give you some ideas)
Here’s how to disable regular expression search/replace only in command mode:
autocmd CmdWinEnter * set nomagic
autocmd CmdWinLeave * set magic
All plugins that depends on regular expression such as white-space remover should works as usual.
Have you enabled magic?
:set magic
Try the Edit Find and replace on the menu bar.

How to search (using regex) for a regex literal in text?

I just stumbled on a case where I had to remove quotes surrounding a specific regex pattern in a file, and the immediate conclusion I came to was to use vim's search and replace util and just escape each special character in the original and replacement patterns.
This worked (after a little tinkering), but it left me wondering if there is a better way to do these sorts of things.
The original regex (quoted): '/^\//' to be replaced with /^\//
And the search/replace pattern I used:
s/'\/\^\\\/\/'/\/\^\\\/\//g
Thanks!
You can use almost any character as the regex delimiter. This will save you from having to escape forward slashes. You can also use groups to extract the regex and avoid re-typing it. For example, try this:
:s#'\(\\^\\//\)'#\1#
I do not know if this will work for your case, because the example you listed and the regex you gave do not match up. (The regex you listed will match '/^\//', not '\^\//'. Mine will match the latter. Adjust as necessary.)
Could you avoid using regex entirely by using a nice simple string search and replace?
Please check whether this works for you - define the line number before this substitute-expression or place the cursor onto it:
:s:'\(.*\)':\1:
I used vim 7.1 for this. Of course, you can visually mark an area before (onto which this expression shall be executed (use "v" or "V" and move the cursor accordingly)).