Vim Regular Expression to Match String with Prefix and Suffix

Vim Regular Expression to Match String with Prefix and Suffix

I want to search a string which starts with "abc" and ends with "xyz" in vim.

Below are the commands I've tried:

:1,$g/abc[\w\W]*xyz/
:1,$g/abc\[\\w\\W\]\*xyz/
:1,$g/abc*xyz/

"[\w\W]*" means the texts between "abc" and "xyz" can be any characters

"1,$" means the search range is from the 1st line to the last line in the file opened by vim.

I found that the search pattern

abc[\w\W]*xyz 

works in

why does it fail in vim?

4

4 Answers

The command below should work unless "any character" means something different for you than for Vim:

:g/abc.*xyz
  • . means "any character except an EOL".
  • * means "any number (including 0) of the previous atom".
  • 1,$ could be shortened to %.
  • :global works on the whole buffer by default so you don't even need the %.
  • The closing / is not needed if you don't follow :g/pattern by a command as in :g/foo/d.
3

Once the file gets too large (say, 1GB), ":g/abc.*xyz" becomes quite slow.

I found that

cat fileName | grep abc | grep xyz >> searchResult.txt

is more efficient than using the search function in vim.

I know that this method may return lines that start with "xyz" and end with "abc".

But since this is a rare case in my file(and maybe this doesn't happen quite often for other people), I think I should write this method here.

1

It seems that inside the collection syntax [..], character classes such as \w can't be used, probably because it tests via character-by-character strategy. From :h /[]:

Matching with a collection can be slow, because each character in the text has to be compared with each character in the collection. Use one of the other atoms above when possible. Example: "\d" is much faster than "[0-9]" and matches the same characters.

You can, however, use similar functionalities specifically prepared for [..] syntax. From :h /[] again :

A character class expression is evaluated to the set of characters belonging to that character class.

examples include:

[:alnum:]     letters and digits                   
[:alpha:]     letters                              
[:blank:]     space and tab characters             
[:cntrl:]     control characters                   
[:digit:]     decimal digits                       
[:graph:]     printable characters excluding space 
[:lower:]     lowercase letters

If you want to find them one by one you can hit

/

and then write

abc.*xyz

and hit enter to find the first occurrence of the pattern. Then use n for the next occurrence and Shift + n for the previous one. This is how I usually do, since for me this is easier to modify those lines.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Marcus Vance
Author

Marcus Vance

Marcus Vance is a cybersecurity auditor and technology writer dedicated to educating the public about online safety, data privacy regulations, enterprise security, and emerging cyber threats.