Sunday, August 11, 2013

Re: vim: how to use back reference to compare strings?

[Please bottom post, per the footer]

On Sat, 10 Aug 2013, ping song wrote:

> I tested this again these test lines, doesn't work.
>
> abc123 bla bla bla abc123 bla bla
> abc123 bla bla bla abc1234 bla bla
> abc123 bla bla bla abc123 bla bla
> abc123 bla bla bla abc1234 bla bla
> abc123 bla bla bla abc123 bla bla
>
> :g#\(abc\d\+\)\(.*\)\(abc\d\+\)\(.*\)#s//\=Diff(submatch(1),submatch(2))/n
>
> I got : "5 substitutions in 5 lines". no message got printed out...
> any idea of what I missed here?
>
> thanks anyway.

Try:

:g#\(abc\d\+\)\>.*\<\%(\1\>\)\@!\(abc\d\+\)#

Here's a diagram. (Not sure if I like it; trying this out):

┌──────────┬ an identifier
│ ├ ending w/a word boundary
│ │
│ │ ┌ (don't need to capture)
│ │ │ ┌ start of a word
│ │ │ │ ┌ non-capturing (but needed for grouping)
│ │ │ │ │
│ │ │ │ │ ┌─────┬ 1st identifier we found
│ │ │ │ │ │ ┌───┼ followed by a word boundary
│ │ │ │ │ │ │ ├ doesn't match here
│ │ │ │ │ │ │ │
│ │ │ │ │ │ │ │ ┌ but there is *an* identifier
│ │ │ │ │ │ │ │ │
├─────────┐├┐├┐├┐├─┐├┐├┐ ├─┐├─────────┐
:g#\(abc\d\+\)\>.*\<\%(\1\>\)\@!\(abc\d\+\)#

In English:

Find lines where:
We capture an identifier.
Match some stuff between.
At a word boundary where the captured identifier doesn't match:
There is some identifier.


Regular expressions have a bad tendency towards being "write-only". I'm
guessing the following code, if you're familiar with VimL, will be more
maintainable, and probably easier to extend. It also dumps everything in a
quickfix list and opens the window if anything matches -- look at the lines
with 'qf' on them if you don't like quickfix:

fun! FindDiffs()
let i = 1
let l = line('$')
let buf = bufnr('.')
let qf = []
while i < l
let m = matchlist(getline(i), '\(abc\d\+\).*\(abc\d\+\)')
if len(m)
let [a, b] = m[1:2]
if a != b
" when not using qf, echo it: echom a '!=' b 'on line' i
call add(qf, {'bufnr': buf, 'lnum': i, 'text': a.' != '.b, 'type': 'W'})
end
end
let i += 1
endw
call setqflist(qf) | cw
endf

--
Best,
Ben

--
--
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/groups/opt_out.

No comments: