Wednesday, December 26, 2012

Re: How to use %03d on existing data

Thanks again Benjamin Haskell see follow up question below

On Wed, Oct 17, 2012 at 10:47 PM, stosss <stosss@gmail.com> wrote:
>
> On Wed, Oct 17, 2012 at 10:32 PM, Benjamin R. Haskell <vim@benizi.com> wrote:
>> On Wed, 17 Oct 2012, stosss wrote:
>>
>>> Okay I have something that should be achievable but I can't figure it out.
>>> I have a lot of files with data for books. Each file is a book and is in
>>> chapters with lines of text.
>>>
>>> sample of existing data:
>>>
>>> <h2>1</h2><p>
>>> 1 line of text.<br>
>>> 2 another line of text.<br>
>>> 3 lines of text.<br>
>>> ...
>>> 10 More lines of text.<br>
>>> ...
>>> 100 Even more lines of text.<br>
>>>
>>> [...]
>>>
>>>
>>> What I want is:
>>>
>>> <h2 id="b001c001">1</h2><p>
>>> <span id="b001c001v001">1</span> line of text.<br />
>>> <span id="b001c001v002">2</span> another line of text.<br />
>>> <span id="b001c001v003">3</span> lines of text.<br />
>>> ...
>>> <span id="b001c001v010">10</span> More lines of text.<br />
>>> ...
>>> <span id="b001c001v100">100</span> Even more lines of text.
>>>
>>> [...]
>>>
>>>
>>> I can't figure out how to use %03d to change my numbers from 1 to 001 I
>>> also would like to figure out how to use setreg() to increase this c001 part
>>> of the id label so it changes to c002 when it is supposed to so I don't have
>>> to reset my map at every chapter. I need to figure out the first part before
>>> I figure out the second part. The examples in the VIM tips aren't helping me
>>> figure this out. Maybe I am looking in the wrong place.
>>>
>>> I tried all sorts of things but nothing worked. I don't remember all the
>>> things I tried but here are a few attempts I made that didn't work:
>>>
>>> :%s@\([0-9]\+\)@%03d\1@
>>> :%s@\([0-9]\+\)@\=printf("%03d"\1)@
>>> :%s@\([0-9]\+\)@\=printf("%03d\1")@
>>>
>>> I don't understand how to use that number format in my search and replace.
>>> The examples on the pages linked above don't give me any clues. It has been
>>> a very long time since I have asked for help with VIM. I usually have been
>>> able to find answers in the tips. But not this time.
>>
>>
>>
>> For the %03d part:
>>
>> :%s@\(\d\+\)@\=printf("%03d", submatch(1))@g
>>
>> See:
>> :help submatch()
>>
>> But, that treats numbers that look like octal incorrectly:
>>
>> E.g.:
>> abc010def -> abc008def
>> (because 010-base-8 is 8-base-10.)
>>
>> So consume the zeros ahead of time:
>> :%s@0\*\(\d\+\)@\=printf("%03d", submatch(1))@g
>>
>> --
>> Best,
>> Ben
>>
>
> Things for the help! And thanks for telling me where I can find more
> information about it. Your first example actually works for me because
> the leading 0s aren't in the beginning.
>
> This helps cut out a step.
>

This works fantastic

:%s@\(\d\+\)@\=printf("%03d", submatch(1))@g

I created a map that changes this:

v001
v010
v100

to:

v1
v10
v100

to:

v2
v11
v101

to:

v002
v011
v101

with:

:%s@v\zs0*\ze@@<CR>:%s@v\zs\d\+\ze@\=submatch(0) +
1@<CR>:%s@\(\d\+\)@\=printf("%03d", submatch(1))@<CR>

That is exactly what I want.

These all work but I would like to be sure I understand how they work.

:%s@v\zs\d\+\ze@\=submatch(0) + 1@

The one above according to :help \= is matching \d\+ and so is
submatch(0) and then + 1 is adding one to the match

:%s@\(\d\+\)@\=printf("%03d", submatch(1))@

This one printf is taking submatch(1) which is grabbing \(\d\+\) and
applying %03d to it so it turns 1 into 001

Am I correct?

What exactly is submatch(0) and submatch(1)? Obviously the 0 and 1
mean something but I am not sure what. I understand what :help
submatch is doing but not totally sure how. Apparently that is where
the 0 and 1 come into play. How can I know what number needs to be in
the ()

Thanks for any help

--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

No comments: