Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pattern found in vim search, but not in vim search and replace?

There is a search and replace operation I am trying to do using backreferencing and regular expressions in vim. Interestingly, it will only recognize the pattern if I do a pure search, but if I do a search and replace it gives me an E486: pattern not found error.

I have a bunch of function calls of the form:

function( Nullable< double >(1.1), map[FOO] );

Where FOO is some different variable name on each line. I want to turn it into

function( othermap[ FOO ], map[FOO] );

If I try

:%s/Null.*\(map[\)\(.*\)\]/othermap[ \2 \], \1\2\]/g

It gives me the "Pattern not found error." Even

:%s/Null.*\(map[\)\(.*\)\]//g 

will not work because it's just not recognizing the pattern. But if I try the following command with the exact same search regex:

/Null.*\(map[\)\(.*\)\]

It highlights correctly. Following which, I can do %s//othermap[ \2 ], \1\2] to do my replacement. So I was able to do my replacement after all, but I can't for the life of me understand why the pattern would be recognized in one case and not in the other.

like image 441
bhh1988 Avatar asked Sep 03 '11 05:09

bhh1988


People also ask

How do I search and replace in Vim?

Basic Find and Replace In Vim, you can find and replace text using the :substitute ( :s ) command. To run commands in Vim, you must be in normal mode, the default mode when starting the editor. To go back to normal mode from any other mode, just press the 'Esc' key.

How do I find and replace every incident of a text string in Vim?

When you want to search for a string of text and replace it with another string of text, you can use the syntax :[range]s/search/replace/. The range is optional; if you just run :s/search/replace/, it will search only the current line and match only the first occurrence of a term.

How do you replace a word with another word in Vim?

Search for text using / or for a word using * . In normal mode, type cgn (change the next search hit) then immediately type the replacement. Press Esc to finish. From normal mode, search for the next occurrence that you want to replace ( n ) and press . to repeat the last change.


1 Answers

I can reproduce the result using copy'n'paste from your question to my vim session. The detailed message I get, though, is:

E486: Pattern not found: Null.*\(map[\)\(.*\)\]/othermap[ \2 \], \1\2\]/g

Note that it has lost the s/ at the start.

However, looking rather carefully at this, the trouble is an unescaped [:

s/Null.*\(map[\)\(.*\)\]/othermap[ \2 \], \1\2\]/g
             ^
             |-- here; you need \[ to match the literal

I don't use the % notation; I would automatically write:

:g/Null.*\(map\[\(.*\)\]\)/s//othermap[\2], \1/g

This has slightly different capturing. There was also no need to use the backslash in \] in the replacement string.

However, this command also works for me:

:%s/Null.*\(map\[\(.*\)\]\)/othermap[\2], \1/g
like image 167
Jonathan Leffler Avatar answered Sep 18 '22 13:09

Jonathan Leffler