Wednesday, October 22, 2014

Re: replace submatches in matchlist

On Mi, 22 Okt 2014, BimbaLaszlo wrote:

> Is there a good way to replace submatches in matchlist() and modify the
> original line with it? I like to write a script which modifies all of the
> submatches in a pattern in one step.
>
> For example the original line is 'some AfooBar' and i like to change it to
> 'some CfooDar':
>
> let pattern = '\(A\)foo\(B\)'
> let line = 'some AfooBar'
> let found = matchlist( line, pattern )
>
> The 'found' contains "['AfooB', 'A', 'B', '', '', '', '', '', '', '']". Now i
> like to modify the 'line' to 'some CfooDar' so the best should be:
>
> let found[1] = 'C'
> let found[3] = 'D'
> let line = MATCHLIST_TO_STRING( found )
>
> As i know it's not possible with the builtin functions, so i need to write
> one. The beginning of the line is not modified till the match, thus i can copy
> that part to the 'new_line':
>
> let new_line = strpart( line, 0, match( line, pattern ) )
>
> But at this point i don't know how to continue. I can append the modified 'A'
> immediately, because the pattern starts with it (in this example, but the user
> can use any kind of pattern). But how can i find out the (offset) index of the
> 'foo' and the 'B'? In this example it's trivial, because there is no other
> 'foo' and 'B' in the line, but let see another example:
>
> let line = 'A A A A A'
> let pattern = 'A \(A\) A \(A\)'
>
> If i like to modify this to 'A B A C A' then it's hard to detect the position
> of the submatches in the 'line'.
>
> One solution is to use submatches for the 'inner words' (like 'foo' in the
> previous example'), but it decreasing the number of useful submatches. For
> example:
>
> let pattern = '\(A\)\(foo\)\(B\)'
> let line = 'some AfooBar'
> let found = matchlist( line, pattern )
> " Remove the full match, we need only the submatches.
> call remove( found, 0 )
> let found[0] = 'C'
> let found[2] = 'D'
> let new_line = strpart( line, 0, match( line, pattern ) ) . join( found, '')
>
> In this case we used one additional submatch, but the 'A \(A\) A \(A\) A' may
> become '\(A \)\(A\)\( A \)\(A\)\( A\)' and it's too lot.
>
> So is there a good way to replace all of the submatches with a new value in
> one step?

Isn't that what you would use submatch() in the replacement part of a :s
command (mentioned in :h sub-replace-expression).

Best,
Christian

--
--
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

---
You received this message because you are subscribed to the Google Groups "vim_use" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vim_use+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

No comments: