regexvimcapture-group

how to store a regex-capture-group as a variable in vim script?


i'm trying to write a vimscript to refactor some legacy code.

roughly i have a lot of files in this format

$this['foo'] = array();
{
    $this['foo']['id'] = 123;
    $this['foo']['name'] = 'name here';
    $this['foo']['name2'] = 'name here2';
    $this['foo']['name3'] = 'name here3';
}

I want to reformat this into

$this['foo'] = array(
    'id' => 123;
    'name' 'name here';
    'name2' 'name here';
    'name3' 'name here';
);

where foo is variable.

I'm trying to match

$this['foo'] = array()
{

with this regex

/\zs\$this\[.*\]\ze = array()\_s{;

so i can execute this code

# move cursor down two lines, visual select the contents of the block { }
jjvi{

# use variable, parent_array to replace 
s/\= parent_array . '\[\([^=]\+\)] = \(.*\);'/'\1' => \2,

but of course i need to let parent_array = /\zs$this[(.*)]\ze = array(); which isnt the right syntax apparently...

TL;DR

function Refactor()

    # what is the proper syntax to do this assignment ?
    let parent_array = /\zs\$this\[.*\]\ze = array()\_s{;

    if (parent_array)
        jjvi{
        '<,'>s/\= parent_array . '\[\([^=]\+\)] = \(.*\);'/'\1' => \2,
    endif

endfunction

EDIT* fixed escaping as per commenter FDinoff


Solution

  • Assuming there's only one such match in a line, and you want the first such line:

    let pattern = '\$this\[.*\]\ze = array()\_s{;'
    if search(pattern, 'cW') > 0
        let parent_array = matchstr(getline('.'), pattern)
    endif
    

    This first locates the next matching line, then extracts the matching text. Note that this moves the cursor, but with the 'n' flag to search(), this can be avoided.