Question

I have a text like this:

NAME_1  : "Some name",
VALUE_1 : "Some text",
NAME_2  : "Some name2",
VALUE_2 : "Some text2",
....

How to transform this text to the following structure using vim scripting language or regex:

1 : {
    NAME  : "Some name",
    VALUE : "Some text"
},
2 : {
    NAME  : "Some name2",
    VALUE : "Some text2"
},

I was looking into the surround.vim plugin. It surrounds with braces well. I tried to modify it to substract by pattern _(\d+) and then prepend this before the braces but I'm not quite familar with the vim scripting so I failed to do that.

Any advice will be appreciated greatly.

Thanks in advance.

Was it helpful?

Solution

You can do this with just one :substitute, using \(...\) capture groups, and re-arranging those submatches in the replacement part. It's only complex because there are several groups to juggle around, and because the pattern spans two lines.

:%s/^\(\w\+\)_\(\d\+\)\(\s*:\s*.*\)\n\(\w\+\)_\2\(\s*:\s*.*\),$/\2 : {\r    \1\3\r    \4\5\r},/

This matches two subsequent lines (note the \n in the pattern). By using the number (second capture group) in the second line, it ensures to get NAME_1 and the corresponding VALUE_2.

Tip: This is easier to build as a search / first, then just reuse the pattern via :%s//...

In the replacement, the newlines are created via the \r. You'll find a more detailed explanation in the help under :help :substitute.

OTHER TIPS

You can do just two substitutions to solve this

%s,NAME_\d\+\,: {\r&,g
%s,VALUE_\d\+,&\r},

the "&" matches all things searched
\r inserts new line
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top