vim does not find and replace simple phrase that is clearly present - vim

I have a simple vim problem that Google hasn't managed to help me with. Any thoughts are appreciated.
I do the following search and replace:
:s/numnodes/numnodes1/g
On a file containing the following text:
numprocs=0
numnodes=0
I get
E486: Pattern not found
The position of the green square which indicates where I'd start typing is clearly above the pattern. I tried searching for other short phrases not involving regex, which are also present, which also fail. A simple /numnodes highlights matches as expected. Does anyone have any idea what might be the matter with vim?

Try :%s/searchphrase/replacephase/g
Without the % symbol Vim only matches and replaces on the current line.

try using this:
:%s/numnodes/numnodes1/g

Related

Why does this regular expression not work in Vim syntax highlighting?

I am attempting to create my own Python syntax highlighting file for Vim.
I'm trying to highlight the class inheritance object and the regex I've created
works in various regex testers, but doesn;t work in Vim. I've read that Vim's regex is close to Perl style
so that is what I've been using.
I'm trying to highlight the word 'Subscribers' in the following text:
class Divisions(Subscribers):
The regex I've composed is:
(?!:class\s\w+)(?<=\()\w+(?=\):)
I'll be honest here, I stumbled into this while I was struggling to make a negative lookbehind work with quantifiers,
which I now understand isn't possible. I was experimenting with the non-capturing group (?:class\s\w+) and accidentally
inserted the exclamation mark which 'magically' solved the problem. At least in the multiple regex testers I was using.
Just for clarity, then follows a look behind (?<=() to caputre but not include the '('
and then a look ahead after the word (?=):) to capture but not include the closing '):'
I've added it to my Vim syntax file as:
syn match pythonClassInherit "(?!:class\s\w+)(?<=\()\w+(?=\):)"
Is this a valid regular expression in Vim? If not, can anybody offer a working solution for Vim?
EDIT: I realized that I've had overcomplicated the issue; you just need a right Vim regex. Try
syntax match pythonClassInherit "\%(class\s\+\h\w*\s*(\s*\)\#<=\h\w*\%(\s*):\)\#="
highlight link pythonClassInherit pythonImport
Then you'll see the result:
You may replace pythonImport by another predefined highlight group.
For highlighting, I found https://learnvimscriptthehardway.stevelosh.com/ (highlighting starts from Chap. 45) helpful. As for regex, romainl's suggestion is awesome.
My first attempt was to use regex \zs. This, unlike \#<=, requires that the syntax group cover the part that comes before \zs, which cannot be satisfied because some other groups have already occupied that part. This led me a complicated solution, by overriding the default highlight groups to include a new group (for Subscribers). But it turns out we really don't have to.
If interested, see Vim syntax file not matching with \zs.
Online regular expression playgrounds don't support Vim's syntax so using them is pointless, here.
See vimregex.com for an overview, :help usr_27 for a gentle tutorial, :help pattern for the definitive reference, and :help perl-patterns for the differences between the Vim syntax and the Perl syntax.

How to replace one character with mutliple characters using search and replace in vim

In vim, I find myself searching for a character and in command mode doing x followed by 10p or 30p or something like that fairly often. I was wondering if there is a regular expression version that I could use in the :s/.../.../ command. \{m} work for matching m counts of of characters in the seach, but its equivalent s/X/X\{10}/gc replaces with the literal stringX{10}.
I've been searching the documentation and haven't found out how to do it yet, if anyone knows of a way I'd appreciate knowing about it.
You can use :h sub-replace-expression like this
%s/X/\=repeat(submatch(0), 10)/gc

VIM select all matching patterns in one line

Can anybody please help on my issue regarding VIM?
This is my scenario:
The red redfox02animal jump over the blue reddog01animal.
I tried this search patten
/red.*[0-9]
but the result is "redfox02animal jump over the blue reddog01". What I want are two matched "redfox02" and "redfox01"
Any advice?
Use /red.\{-}[0-9]\+ instead of /red.*[0-9], the former is non-greedy, while the latter (default) is greedy.
this should go too:
/red\D*\d\+
Note that this gives the same matches as Tobi's answer, the first match is:
red redfox02
if you just want to have redfox02 and reddog01 (there is no redfox01 in your input, you cannot get it, as you stated in your question), you can try:
/red[^0-9 ]\d\+

Vi search and replace with slashes

I am trying to run this command in vi
:s/href="\//href="http:\/\/website.com\/folder\/subfolder\//g
but got this error E486: Pattern not found: href="\/
What am i doing wrong?
That error means pretty much what it says. vi didn't find any pattern href="/ (ignoring escapes) in your file.
Sometimes it's easier to use something besides / for the search delimiter if your search has a lot of slashes, so you don't need to escape them all. Try replacing the / delimiter with # instead, like this:
s#href="/#href="http://website.com/folder/subfolder/#g
Then maybe you can more easily see what's wrong with your pattern:
becouse there are many '/' chars, try use another delimiter, ex ',':
:s,some/pattern/with/slashes,new/string,g
On another note. That substition worked for me. Just copied and pasted. Are you on the same line that you are trying to perform the substitution on? the 'g' is meant globally on the line you are on. If you need to perform the search and replace on the file the use :%s/

Delete anything other than pattern

Let's say this is my text:
this is my text this
is my text this is my text
my text is this
I would like to highlight all text except pattern and delete the highlighted text.
p.e. text: this must be the result.
text
texttext
text
I've found the code how to select all text except pattern:
\%(\%(.{-}\)\#!text\zs\)*
however I don't know how to delete all highlighted text.
This doesn't work:
:%s/\%(\%(.{-}\)\#!bell\zs\)*//
Can anyone help me?
Try this:
:%s/\(^\|\(text\)\#<=\).\{-}\($\|text\)\#=//g
Explanation:
\(^\|\(text\)\#<=\) # means start of line, or some point preceded by “text”
.\{-} # as few characters as possible
\($\|text\)\#= # without globbing characters, checking that we reached either end of line or occurrence of “text”.
Another way to do it:
Create a function that count matches of a pattern in a string (see :help match() to help you design that)
Use: :%s/.*/\=repeat('text', matchcount('text', submatch(0)))
Forgive me, because I'm not a vim expert, but wouldn't prepending the search with v find the inverse so that you could do something like this?
:v/pattern/d
I've implemented Benoit's clever regular expression as a custom :DeleteExcept command in my PatternsOnText plugin. It offers other related commands like :SubstituteExcept or :SubstituteInSearch, too.
OP's example would be
:%DeleteExcept /text/
Comparing that with #Benoit's explicit command (:%s/\(^\|\(text\)\#<=\).\{-}\($\|text\)\#=//g), it's a lot simpler.

Resources