Home > Enterprise >  Alphanumeric substitution with vim
Alphanumeric substitution with vim

Time:04-20

I'm using the vscode vimplugin. I have a bunch of lines that look like:

Terry,169,80,,,47,,,22,,,6,,

I want to remove all the alphanumeric characters after the first comma so I get:

Terry,,,,,,,,,,,,,

In command mode I tried:

s/^. \,[a-zA-Z0-9-]\ //g

But this does not appear to do anything. How can I get this working?

edit:

s/^[^,]\ ,[a-zA-Z0-9-]\ //g

CodePudding user response:

\ is greedy; ^.\ , eats the entire line up to the last ,.

Instead of the dot (which means "any character") use [^,] which means "any but a comma". Then ^[^,]\ , means "any characters up to the first comma".

The problem with your requirement is that you want to anchor at the beginning using ^ so you cannot use flag g — with the anchor any substitution will be done once. The only way I can solve the puzzle is to use expressions: match and preserve the anchored text and then use function substitute() with flag g.

I managed with the following expression:

:s/\(^[^,]\ \)\(,\ \)\(.\ \)$/\=submatch(1) . submatch(2) . substitute(submatch(3), '[^,]', '', 'g')/

Let me split it in parts. Searching:

\(^[^,]\ \) — first, match any non-commas
\(,\ \) — any number of commas
\(.\ \)$ — all chars to the end of the string 

Substituting:

\= — the substitution is an expression

See http://vimdoc.sourceforge.net/htmldoc/change.html#sub-replace-expression

submatch(1) — replace with the first match (non-commas anchored with ^)
submatch(2) — replace with the second match (commas)
substitute(submatch(3), '[^,]', '', 'g') — replace in the rest of the string

The last call to substitute() is simple, it replaces all non-commas with empty strings.

PS. Tested in real vim, not vscode.

  • Related