Home > Software design >  How can I use Neovim regex to make a separated selection (of two characters not following one anothe
How can I use Neovim regex to make a separated selection (of two characters not following one anothe

Time:05-11

I'm attempting to replace all strings in a text file surrounded by single quotes and ending with an @ first followed by any number and then any mix of any other letter(s) or #(s) like these:

'[email protected]'
'otherpackage@14'
'[email protected]'

and I wish to select only the single quotes and remove them like so:

export MYVAR="/dir/'[email protected]':$MYVAR" 

to:

export MYVAR="/dir/[email protected]:$MYVAR"

in the entire file. I figured out a way to remove the proceeding single quote and preceding single quote in two separate commands (using vim's zs and ze, similar to positive and negative lookarounds):

:%s/'.*@.[0-9]*.*\zs'//g 
:%s/\zs'\ze.*@.[0-9]*.*//g

However, I am curious about doing it in a single operation as I want to learn more about using Neovim, and apply the answer to future operations.

I am actually using Neovim, if that comes with any additional features related to this.

CodePudding user response:

You can replace matches of the following regular expression with the content of capture group 1.

'([^@']*@\d[^@']*)'

Demo

I'm not familiar with Vim's regex engine, but I understand it is quite robust. Considering that the regular expression I have suggested is nothing fancy (just making use of a capture group) I'm confident it should work in Vim.

The regular expression can be broken down as follows.

'           # match a single quote
(           # begin capture group 1
  [^@']*    # match zero or more characters other than '@' and a single-quote
  @\d       # match '@' followed by a digit ofollowed by zero or more characters
            # other than '@' and a single-quote
  [^@']*    # match zero or more characters other than '@' and a single-quote
)           # end capture group 1
'           # match a single quote

I've assumed that there can be at most one '@' between asterisks, but if more that one is permitted (if, for example, 'a@11@22*' is to be converted to a@11@22*) change the regular expression to

'([^']*@\d[^']*)'

CodePudding user response:

You need to use

%s/'\([^@'0-9]*@[0-9][^']*\)'/\1/g

Details:

  • ' - a single quote
  • \( - start of a capturing group
    • [^@'0-9]* - zero or more chars other than @, ' and digits
    • @ - a @ char
    • [0-9] - a digit
    • [^']* - zero or more chars other than a ' char
  • \)' - end of the capturing group.

The replacement is \1, the Group 1 backreference/placeholder.

  • Related