My Vim replace with a regex is throwing a `E488: Trailing characters` - regex

I'm trying to find all instances of a Twitter handle, and wrap an anchor tag around them.
:%s/\(#[\w]\)/<a href="http://www.twitter.com/\1">\1<\/a>/gc
Which gives me:
E488: Trailing characters

If you have this when replacing within a selected block of text, it may be because you mistakenly typed %s when you should only type s
I had this happen by selecting a block, typing : and at the prompt :'<,'>, typing %s/something/other/ resulting in :'<,'>%s/something/other/ when the proper syntax is :'<,'>s/something/other/ without the percent.

When the separator character (/ in your case) between {pattern} and {string} is contained in one of those, it must be escaped with a \. A trick to avoid that is to use a different separator character, e.g. #:
:%s##\(\w\+\)#\0#gc
PS: If it should do what I think it should do, your pattern is wrong; see my correction.

I had this issue and couldn't make it go away until I found out that the .vimrc file that I had parts that I copied from else where that contained abbreviations, like this for example:
abbrev gc !php artisan generate:controller
That abbreviation would mess up my search and replace commands which usually look like this:
:%s/foo/bar/gc
by expanding that gc into !php artisan generate:controller, except, that it wouldn't do it on the spot/ in real time. The way that I clued in was by looking through the command history (by pressing : and the up arrow) and seeing
:%s/foo/bar/!php artisan generate:controller
So if you're getting trailing character errors no matter what you do I'd look inside
~/.vimrc
and see if you can find the problem there.

I had the same problem.
Only using other delimiters didn't help. So, additionally
I didn't select any row.
And didn't use g for global.
so just
:%s#to_be_replaced#replacement#
did the job. Changed all occurrences of 'to_be_replaced' with 'replacement'.

:%s/\/apps/log_dir/g
where string to replace=/apps
and replaced string=log_dir
as we saw / so we need to use "\/"

This is how I caused my "E488: Trailing characters"
Occasionally the muscle memory in my brain skips a beat as it did today causing me to seek the reason for my E488: Trailing characters.
:%s/searchItem/changeTo/s
The s at the end caused my E488: Trailing characters.
I should have used a g
:%s/searchItem/changeTo/g
Placing the g at the end worked as always.

Related

Simple Regex slipped up by Pile Delimeter?

I've a simple regex to create and for the life of me cant get it to work due to the Pipe Delimiter causing headaches.
I'm just trying to add a file extension, by looking at a previous extension, and adding that to the end of the current name.
(Find)
old.jpg|new
(Replace)
old.jpg|new.jpg
I've used a good combination but having the Pipe seems to trip me up.
Are there any suggestions or tips?
You have to escape the pipe, either with \| or [|].
The | character has special meaning. You need to escape it, for example by using a character class: [|].

How do I escape comma in WMIC inside like string

I wish to be able to run a query like the following:
wmic path Win32_Service where "DisplayName like 'FooBarService % (X, Y)'" get *
But, it doesn't work because of the comma inside the like string. The error I get is "Invalid Verb." I tried escaping it with a backslash, and I tried escaping it using brackets as underscores are meant to be escaped, and both resulted in the "Invalid Verb." error.
As a less-than-ideal workaround, I can replace the commas with underscores, and it works, but the underscore will match any single character rather than just the comma, so I'd rather find a way to escape the commas.
Is there a way to escape the comma like in this example?
One way I have found to include a comma in the like clause is to place the entire where expression in parentheses. Unfortunately, I also found that this means I cannot include a close paren in the string at the same time (but an open paren is okay). I experimented with the /trace:on option to see what was going on under the covers a little bit and it helped me find a couple things the program accepts:
Here is an example I got to work with a comma, but it apparently cannot contain a close paren:
C:\> wmic /trace:on path Win32_Service where (Description like '%(%, %') get DisplayName
And here is an example I got to work with both open and close parentheses, but apparently it cannot contain a comma (obviously, this is quite similar to your original example):
C:\> wmic /trace:on path Win32_Service where "Description like '%(TAPI)%'" get DisplayName
It seems like the parser just isn't complex enough to handle these cases, but with tracing on, you can see the WMI Win32 functions that it uses, so maybe you could write your own program that uses the functions directly. I think IWbemServices::ExecQuery is capable of what you're looking to do.

How to read this command to remove all blanks at the end of a line

I happened across this page full of super useful and rather cryptic vim tips at http://rayninfo.co.uk/vimtips.html. I've tried a few of these and I understand what is happening enough to be able to parse it correctly in my head so that I can possibly recreate it later. One I'm having a hard time getting my head wrapped around though are the following two commands to remove all spaces from the end of every line
:%s= *$== : delete end of line blanks
:%s= \+$== : Same thing
I'm interpreting %s as string replacement on every line in the file, but after that I am getting lost in what looks like some gnarly variation of :s and regex. I'm used to seeing and using :s/regex/replacement. But the above is super confusing.
What do those above commands mean in english, step by step?
The regex delimiters don't have to be slashes, they can be other characters as well. This is handy if your search or replacement strings contain slashes. In this case I don't know why they use equal signs instead of slashes, but you can pretend that the equals are slashes:
:%s/ *$//
:%s/ \+$//
Does that make sense? The first one searches for a space followed by zero or more spaces, and the second one searches for one or more spaces. Each one is anchored at the end of the line with $. And then the replacement string is empty, so the spaces are deleted.
I understand your confusion, actually. If you look at :help :s you have to scroll down a few pages before you find this note:
*E146*
Instead of the '/' which surrounds the pattern and replacement string, you
can use any other 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+/+//+
I do not know vim syntax, but it looks to me like these are sed-style substitution operators. In sed, the / (in s/REGEX/REPLACEMENT/) can be uniformly replaced with any other single character. Here it appears to be =. So if you mentally replace = with /, you'll get
:%s/ *$//
:%s/ \+$//
which should make more sense to you.

How to match a decimal letter and blank in vim?

I need to change
1 A
2 B
3 C
4 D
to
A
B
C
D
which means the decimal letter at the begining of every line and the following one or more blank should be deleted .
I'm only familiar with Reqex in Perl, so I try to use :%s/^\d\s+// to solve my problem, but it does not work. so does anyone of you can tell me how to get the work done using vim ?
thanks.
Vim needs a backslash for +, so try
:%s/^\d\s\+//
One way is to use the global command with the search-and-replace command:
:g/^[0-9] */s//
It searches for the sequence:
start of line ^
a digit [0-9]
a space <space>
zero or more spaces <space>*
and then substitutes it for nothing (s//).
While you can do a similar thing with just the search-and-replace command on its own, it's useful to learn the global command since you can do all sorts of wonderful things with the lines selected (not just search and replace).
Use the following
:%s/^[0-9] *//
You should use instead
:%s/^\d\s\+//
Being a text editor, vim tends to treat more characters literally‒as text‒when matching a pattern than perl. In the default mode, + matches literal +.
Of course, this is configurable. Try
:%s/\v^\d\s+//
and read the help file.
:help magic
You can also use the Visual Block mode (Ctrl+V), then move down and to the right to highlight a block of characters and use 'x' to remove them. Depending on the layout of the line, that may in fact be quicker (and easier to remember).
If you still want to use Perl for this, you can:
:%!perl -pe 's/^\d\s+//'
Vim will write the file to a temporary file, run the given Perl script on it, and reload the file into the edit buffer.
Escape the plus sign:
:%s/^\d\s\+//
If it's in a column like that you could go into the column visual mode by pressing:
esc ctrl+q
then you can highlight what you want to delete

Regex search and replace in VI

I have a document with lots of <swf...>.....</swf> in it. I would like to remove all these. Using vi when i type
:%s/\<swf[^\/swf>]+\/swf\>//g
I was hoping this would work, but it doesn't match anything.
You can remove all those from the buffer with this command:
:%s!<swf.\{-}/swf>!!
if you also have tags that might be split on two lines, you can add the \_ modifier to make . match newlines too:
:%s!<swf\_.\{-}/swf>!!
this assuming you want to remove both the tags and what they contain, if you just want to get rid of the tags and keep the content
:%s!</\?swf.\{-}>!!
Notes:
you don't need to escape < or >
you can choose whatever pattern delimiter you wish: Vim will use the first character you put after the s in the substitute command: this takes away the need to escape forward slashes in your pattern
EDIT: extending my answer after your comment
this is exactly like /STRING/REPLACE/g I only used a ! instead of / so that I don't have to quote the backslash in the pattern (see my second point above)
I didn't add the g modifier at the end since I have :set gdefault in my .vimrc since forever (it means that by default Vim will substitute all matches in a line instead of just the first, thus reverting the meaning of /g)
\{-} is the "ungreedy" version of the * quantifier, i.e. it matches 0 or more of the preceding atom but take as few as possible -- this helps you make sure that your search pattern will extend to the first "closing tag" instead of the last.
HTH
The problem here is that the [] is a character class, so you are telling it that between the swf opening and closing tags, the letters s, w and f cannot appear anywhere, in any order.
You could try a non-greedy match instead:
\<swf.\{-}\/swf\>
Note that . does not allow newline by default.
I don't use Vim though, so I used this guide to discover the syntax. I hope it is correct.