2

I want to replace if (condition) //comment \n\s*{ (\n - newline, \s* 0 or more whitespaces), or rather restructure it, so brace is on same line as if and comment is moved to next one and is indented by one tab more.

It's a Vim practice task, so please don't give me whole solution, instead help me understand what I'm missing.

My regex works and catches what I want (starting with comment on purpose):

:%s#\(//\)\(.\)*\n\(\s\)*{#{\r\t\3\1 \2#g

My replace pattern however doesn't catch groups, using \1 \2 \3 doesn't work. To be more precise, only \1 works.

I get a brace, a new line, one more indent as wanted, then groups (except for \1 (meaning //) are NOT there:

if (condition) {
    //

No comment text, no tabs/whitespaces aside from one I specifically put there. What am I missing?

  • 1
    What does that \n and \s mean? Are they literal characters or used as their original meaning? – SibiCoder Aug 22 '16 at 11:40
  • 3
    I think \n and \s are newlines and space characters, as his given regex won't match otherwise.. from what I could make out, (.\)*\n should be (.*\)\n – Sundeep Aug 22 '16 at 11:44
  • 1
    @spasic please post this as an answer so I can accept, as this is precisely what I was missing, my thanks. Groups were captured as they were stated, duh! – LIttle Ancient Forest Kami Aug 22 '16 at 12:21
  • 3
    Another note: it's not really worth putting constant text like "//" into a group, because you could just put // on the other side, rather than \1 – DJMcMayhem Aug 22 '16 at 13:57
  • @DJMcMayhem definitely. It's just that I was trying to see if there's a problem with groups or what I put in them, thus // was used as test input. Thank you though! – LIttle Ancient Forest Kami Aug 22 '16 at 15:02
4

Given this text

if (condition) //comment
    {

the following substitute

:%s#\(//\)\(.\)*\n\(\s\)*{#{\r\t\3\1 \2#g

gives:

if (condition) {
     // t

I don't fully understand, but \(.\)* would repeat the atom of capturing any single character zero or more times, resulting in capturing the last character of first line t

As the intention was to capture all the text following //, * should have been inside the capturing group. Same goes for \(\s\)*. The g flag is not needed as well

:%s#\(//\)\(.*\)\n\(\s*\){#{\r\t\3\1 \2#

which gives

if (condition) {
        // comment

Using the very magic modifier, the regex would be (see :h \v for help)

:%s#\v(//)(.*)\n(\s*)\{#{\r\t\3\1 \2#
  • 3
    Thank you. Very magic comes next, it's just that when debugging I went back to escaping manually as I knew it more. Good thing about /g, I used it so often lately that I started appending it by habit... – LIttle Ancient Forest Kami Aug 22 '16 at 15:01

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.